/* ═══════════════════════════════════════════════════════════════════════════
   THE SLAB — the material.

   ONE LIGHT, DECLARED ONCE, and everything below agrees with it: from above
   and a little to the LEFT, at about eleven o'clock. So every slab carries a
   lit hairline along its TOP edge, a shaded one along its BOTTOM, its cast
   shadow falls down and to the RIGHT, and the specular band crosses the face
   from the upper left. Nothing in this file contradicts that.

   A SLAB IS A SOLID, NOT A CARD. It is built as:

     .cast    a coloured shadow on the floor, which is a separate plane
     .slab    the transform the behaviour hands it — preserve-3d
       .body    the extrusion: N shells stepped back in Z
       .back    the far face, so the object is closed when it turns past 90°
       .face    the LIVE widget, at z = 0
       .glaze   the glass: tint, refraction, and the frost
       .rim     the lit bevel — a hairline that follows the radius
       .gloss   the specular band

   ⚠ EVERY LENGTH THAT DESCRIBES THE OBJECT IS IN `px` OF SCENE SPACE, because
   a 3-D transform is applied in the parent's pixel space and a percentage of a
   rotated box is not a thing. The one exception is inside .face, which is the
   widget's own container-query world and is measured in cqw.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* the object */
  --w:168px;            /* a slab's width — every distance in the scene is a
                           multiple of this, so the rig re-scales on one number */
  --r:26px;             /* corner radius. Big: these are squircles, not cards */
  --thick:16px;         /* how deep the solid is */
  --shells:16;          /* how many laminations make the body. Dense enough
                           that the edge reads solid at a grazing angle */
  /* the light */
  --lx:-0.34;           /* eleven o'clock, as a direction, so JS and CSS cannot
                           disagree about where the light is */
  --ly:-0.94;
  --key:rgba(255,255,255,.92);
  --shade:rgba(0,0,0,.34);
  /* the slab's own colour — written per-slab by look.js */
  --tint:#8e9bb2;
  --tint2:#c9d2e0;
  --edge:#aab6c8;
  --glow:rgba(140,160,200,.55);
}

/* ── the transform the behaviour wrote ─────────────────────────────────── */
.slab{
  position:absolute;
  left:50%; top:50%;
  width:var(--w); height:var(--w);
  margin:calc(var(--w) / -2) 0 0 calc(var(--w) / -2);
  border-radius:var(--r);
  transform-style:preserve-3d;
  /* ⚠ ONE transform, written whole every frame. Composing it out of several
     properties means the browser interpolating them separately the moment
     anything transitions, and a slab that translates and rotates on two
     different curves does not read as one object. */
  transform:
    translate3d(var(--px), var(--py), var(--pz))
    rotateX(var(--rx)) rotateY(var(--ry)) rotateZ(var(--rz))
    scale(var(--sc));
  opacity:var(--op,1);
  will-change:transform;
}

/* the body — a stack of laminations. Each is the slab's own silhouette, so a
   rounded corner extrudes as a rounded corner, which four flat side quads
   could never give you. */
.body{position:absolute;inset:0;transform-style:preserve-3d;border-radius:inherit}
.sh{
  position:absolute; inset:var(--in, 0px);
  /* the lamination's own colour, already darkened for how deep it sits */
  --sh-c:color-mix(in oklab, var(--edge), black calc(var(--d) * var(--sh-fall, 34%)));
  border-radius:inherit;
  transform:translateZ(var(--sz));
  backface-visibility:hidden;
  /* the light again: the top of the edge catches it, the bottom does not */
  background:linear-gradient(
    var(--lit-a, 200deg),
    color-mix(in oklab, var(--sh-c), white 60%) 0%,
    color-mix(in oklab, var(--sh-c), white 12%) 9%,
    var(--sh-c) 46%,
    color-mix(in oklab, var(--sh-c), black 40%) 100%);
  /* laminations further back sit in their own shadow — as a COLOUR, never a
     filter: a filter here is one render surface per lamination */
}

/* the far face — without it a slab turned past ninety degrees is hollow, and
   a hollow solid is the one thing that gives the whole trick away */
.back{
  position:absolute; inset:0; border-radius:inherit;
  transform:translateZ(calc(var(--thick) * -1)) rotateY(180deg);
  background:linear-gradient(var(--lit-a, 200deg),
    color-mix(in oklab, color-mix(in oklab, var(--tint), #6b6f76 62%), black 34%),
    color-mix(in oklab, color-mix(in oklab, var(--tint), #6b6f76 62%), black 58%));
  opacity:var(--backface, .9);
  backface-visibility:hidden;
}

/* ── the face: the live widget ─────────────────────────────────────────── */
.face{
  position:absolute; inset:0;
  border-radius:inherit;
  overflow:hidden;
  background:var(--face-bg, var(--tint2));
  transform:translateZ(.6px);   /* off the first lamination, or they z-fight */
  backface-visibility:hidden;
}
/* the widget lays itself out at its own 140 and is SCALED to the slab — a true
   miniature, never a re-layout, which is what keeps every cqw inside it
   honest at any size the rig draws it at. */
.face .field{
  position:absolute; left:0; top:0;
  width:140px; height:140px;
  transform-origin:0 0;
  transform:scale(var(--fk));
  container-type:inline-size; container-name:tile;
}

/* ── the glass ─────────────────────────────────────────────────────────── */
/* Frost, tint and refraction, all on one plane above the widget. The look
   decides how much of each; at zero it is invisible and the widget is simply
   itself. */
.glaze{
  position:absolute; inset:0; border-radius:inherit;
  transform:translateZ(1.2px);
  pointer-events:none;
  opacity:var(--glaze,0);
  background:
    /* the rim: the long path through the glass */
    radial-gradient(140% 120% at 50% 50%,
      transparent 0%, transparent 38%,
      color-mix(in oklab, var(--edge) 55%, transparent) 82%,
      color-mix(in oklab, var(--edge) 88%, transparent) 100%),
    /* one soft wash from the light's own corner, so the sheet is not flat */
    linear-gradient(var(--lit-a, 200deg),
      color-mix(in oklab, var(--tint) 30%, transparent) 0%,
      transparent 46%,
      color-mix(in oklab, var(--tint2) 34%, transparent) 100%);
  /* ⚠ no mix-blend-mode: it would flatten the slab's 3-D context */
}

/* ⚠ THE HALO WAS THE BIGGEST THING KEEPING THE RIG FROM READING LIKE THE
   RENDER. A wide coloured bloom round every slab is a glow, and a rendered
   chip on a sweep has none — it has an EDGE. The bloom is a fraction of what
   it was and the gloss carries the difference, so what says "glass" is a
   highlight with a shape rather than a light leaking out of the object.  */

/* THE MICRO-TEXTURE, and it is OFF by default.
   ⚠ Two hairline rasters at a hair over one device pixel read as a finish at
   a grazing angle and as a VISIBLE GRID head-on — which is the angle most of
   these arrangements are looked at, so every tile wore a mesh. `--grain-k` is
   a control on the rail, at 0 unless somebody asks for it. */
.grain{
  position:absolute; inset:0; border-radius:inherit;
  transform:translateZ(1.4px);
  pointer-events:none;
  opacity:calc(var(--grain,0) * var(--grain-k, 0));
  background:
    repeating-linear-gradient(0deg, rgba(255,255,255,.9) 0 .5px, transparent .5px 3px),
    repeating-linear-gradient(90deg, rgba(0,0,0,.30) 0 .5px, transparent .5px 3px);
  /* ⚠ `overlay` here flattened the whole slab. A symmetric pair of hairlines,
     one light and one dark, is what overlay was doing anyway. */
}

/* the bevel. ⚠ NOT a border: a border is drawn round the element's box and on
   a rounded rect it would run across the corner. This is an inset ring that
   follows the radius, lit at the top and shaded at the foot — the same two
   hairlines every raised thing in this repo carries. */
.rim{
  position:absolute; inset:0; border-radius:inherit;
  transform:translateZ(1.6px);
  pointer-events:none;
  box-shadow:
    inset 0 1.2px 0 -0.2px var(--key),
    inset 0 -1.2px 0 -0.2px var(--shade),
    inset 1px 0 0 -0.4px rgba(255,255,255,.36),
    inset 0 0 0 1px var(--ring, rgba(255,255,255,.16));
  opacity:var(--rim,1);
}

/* the bloom — the edge, on fire, in the air just outside the object */
.bloom{
  position:absolute; inset:-3px; border-radius:calc(var(--r) + 3px);
  transform:translateZ(-0.4px);
  pointer-events:none;
  opacity:var(--bloom,0);
  box-shadow:
    0 0 var(--bloom-r, 13px) color-mix(in oklab, var(--edge) 46%, transparent),
    0 0 calc(var(--bloom-r, 13px) * 2.4) color-mix(in oklab, var(--edge) 18%, transparent);
}

/* the specular. One band crossing from the upper left, its position driven by
   how the slab is turned — which is the whole reason a slab reads as a
   physical thing rather than a picture of one: turn it and the light MOVES. */
.gloss{
  position:absolute; inset:0; border-radius:inherit;
  transform:translateZ(1.9px);
  pointer-events:none;
  opacity:var(--gloss,.5);
  background:linear-gradient(
    var(--gloss-a, 118deg),
    transparent calc(var(--gloss-p, 40%) - 34%),
    rgba(255,255,255,.16) calc(var(--gloss-p, 40%) - 7%),
    rgba(255,255,255,.34) var(--gloss-p, 40%),
    rgba(255,255,255,.13) calc(var(--gloss-p, 40%) + 8%),
    transparent calc(var(--gloss-p, 40%) + 30%));
  /* ⚠ `soft-light` here flattened the whole slab — see .grain */
}

/* ── the cast shadow ───────────────────────────────────────────────────── */
/* Lives on the FLOOR, not on the slab, because a shadow belongs to the thing
   it is falling on. It is the slab's own colour: a coloured object over a pale
   ground throws a coloured shadow, and it is the single detail that most makes
   the reference renders look like photographs. */
.cast{
  position:absolute; left:50%; top:50%;
  width:var(--w); height:var(--w);
  margin:calc(var(--w) / -2) 0 0 calc(var(--w) / -2);
  border-radius:calc(var(--r) * 1.4);
  transform:translate3d(var(--cx), var(--cy), 0) scale(var(--cs, 1));
  background:radial-gradient(closest-side at 50% 50%,
    var(--glow) 0%,
    color-mix(in oklab, var(--glow), transparent 46%) var(--c1, 34%),
    color-mix(in oklab, var(--glow), transparent 82%) var(--c2, 66%),
    transparent 100%);
  opacity:var(--co, .5);
  pointer-events:none;
}

/* ═══ THE LOOKS ════════════════════════════════════════════════════════════
   Five materials over the same object. A look decides what the slab is MADE
   of and may not move a box — every one of them is the same geometry, so
   switching between them is a change of material and never a change of
   arrangement. */

/* SOLID — the honest default. The widget on an opaque body with a dark edge,
   which is the one look where a widget is as legible as it is on a phone. */
.look-solid .face{opacity:1}
.look-solid{--glaze:0; --bloom:0; --grain:.10; --gloss:.34; --rim:1; --ring:rgba(255,255,255,.12)}

/* GLASS — the render everybody has seen: saturated, translucent, the edge a
   bright bar of the slab's own colour and the shadow the same colour again.
   The widget reads THROUGH it rather than under it. */
.look-glass{--backface:.88; --face-bg:color-mix(in oklab, var(--tint2) 30%, white); --glaze:.92; --bloom:.13; --bloom-r:9px; --grain:.16; --gloss:.95; --co:.62; --cb:22px; --ring:rgba(255,255,255,.40)}
.look-glass .face{opacity:.94}
.look-glass .sh{--sh-fall:52%}
.look-glass .rim{
  box-shadow:
    inset 0 1.4px 0 -0.2px rgba(255,255,255,.98),
    inset 0 -1.6px 0 -0.2px color-mix(in oklab, var(--edge), black 20%),
    inset 0 0 0 1px rgba(255,255,255,.42),
    inset 0 0 14px -4px color-mix(in oklab, var(--edge) 80%, white);
}

/* FROST — inkwell's card. Almost opaque, the colour drained out of it, and
   the only thing saying which way it is turned is that a face turned away
   goes DARKER: `color -= (1 - |n.z|) * .2`, written here as a brightness the
   rig computes off the slab's own normal. */
.look-frost{--backface:.8; --face-bg:color-mix(in oklab, var(--tint2) 22%, white); --glaze:.86; --bloom:.05; --bloom-r:7px; --grain:.34; --gloss:.22; --co:.30; --cb:26px; --ring:rgba(255,255,255,.22)}
.look-frost .face{opacity:.94; filter:saturate(.72) contrast(.96)}
.look-frost .glaze{
  /* a scattering surface: no band, no rim, just more light where the light is */
  background:
    radial-gradient(120% 110% at 26% 4%, rgba(255,255,255,.92), rgba(255,255,255,.34) 52%, rgba(255,255,255,.12) 100%),
    linear-gradient(170deg, rgba(255,255,255,.30), rgba(228,232,240,.44));
}
/* ⚠ frost has NO sharp specular. A matte surface with a hard highlight band on
   it is a glossy surface, which is the thing frost is not. */
.look-frost .gloss{opacity:0}
.look-frost .face{opacity:.94; filter:saturate(.62) contrast(.92) brightness(1.04)}
.look-frost .rim{
  box-shadow:
    inset 0 1px 0 -0.3px rgba(255,255,255,.7),
    inset 0 -1px 0 -0.3px rgba(0,0,0,.10),
    inset 0 0 0 1px rgba(255,255,255,.30),
    inset 0 0 22px -6px rgba(255,255,255,.7);
}
.look-frost .sh{--sh-fall:40%}

/* LIQUID — the iOS-26 tile: a white squircle that is mostly light, a very
   large radius, one soft specular arc and almost no edge at all. The widget
   sits INSIDE it rather than being it, which is why the face is inset. */
.look-liquid{--backface:.75; --face-bg:#fbfcfe; --r:52px; --glaze:.55; --bloom:.07; --bloom-r:8px; --grain:.08; --gloss:.72; --co:.34; --cb:30px; --ring:rgba(255,255,255,.55)}
.look-liquid .face{
  inset:15px; border-radius:calc(var(--r) - 19px);
  /* a plate LYING ON the tile: its own contact shadow under it, its own lit
     top edge, and a hair of glass over its own content */
  box-shadow:
    0 1px 0 rgba(255,255,255,.95),
    0 2px 3px rgba(0,0,0,.05),
    0 10px 20px -8px rgba(20,24,34,.30),
    inset 0 0 0 .8px rgba(255,255,255,.55);
}
.look-liquid .gloss{opacity:.30}
.look-liquid .glaze{
  background:
    /* the one broad arc R6 is carrying, from the light's own corner */
    radial-gradient(150% 80% at 18% -12%, rgba(255,255,255,1), rgba(255,255,255,.45) 38%, transparent 66%),
    radial-gradient(90% 60% at 84% 108%, rgba(214,224,240,.55), transparent 62%),
    linear-gradient(180deg, rgba(255,255,255,.70), rgba(238,242,249,.52));
  mix-blend-mode:normal;
}
.look-liquid .sh{--sh-fall:34%}

/* CHROME — the extruded logo at the end of the reel: the face keeps the
   widget, the BODY goes metal, and a matcap-ish sweep runs round the edge. */
.look-chrome{--glaze:.40; --bloom:.09; --bloom-r:8px; --grain:.05; --gloss:1; --co:.44; --ring:rgba(255,255,255,.5)}
.look-chrome .sh{
  --sh-fall:10%;
  background:linear-gradient(
    var(--lit-a, 200deg),
    #ffffff 0%, color-mix(in oklab, var(--edge), white 30%) 18%,
    color-mix(in oklab, var(--edge), black 10%) 46%,
    #2c3038 66%, color-mix(in oklab, var(--edge), white 10%) 88%, #6a7280 100%);
}
.look-chrome .face{opacity:.88; filter:contrast(1.12) saturate(.72)}
.look-chrome .glaze{
  /* the room, reflected: bright sky above, dark floor below, and a hard line
     where they meet — that line is the whole of it */
  background:linear-gradient(
    calc(var(--lit-a, 200deg) + 180deg),
    rgba(255,255,255,.92) 0%,
    rgba(232,238,248,.72) 34%,
    rgba(210,218,232,.55) 47.5%,
    rgba(26,30,38,.55) 48.5%,
    rgba(58,64,76,.42) 62%,
    rgba(150,158,172,.34) 100%);
}
.look-chrome .gloss{opacity:1}
.look-chrome .rim{
  box-shadow:
    inset 0 1.6px 0 -0.2px rgba(255,255,255,1),
    inset 0 -1.6px 0 -0.2px rgba(0,0,0,.55),
    inset 0 0 0 1px rgba(255,255,255,.5);
}

/* ── reduced motion ────────────────────────────────────────────────────── */
/* The behaviours already take a `motion` knob and the rig hands them 0, so
   nothing here has to fight a transform that is being written every frame. */
@media (prefers-reduced-motion:reduce){
  .slab{will-change:auto}
}


/* ═══ DELAMINATION ═════════════════════════════════════════════════════════
   An element that is not on this plane keeps its BOX and loses its PAINT.
   Every property here is one an element uses to draw ITSELF; nothing here
   touches layout, because moving a box would move the children that are on
   other planes and the tile would come apart into pieces that no longer line
   up with each other. */
.lz-off{
  background:none !important;
  box-shadow:none !important;
  border-color:transparent !important;
  color:transparent !important;
  fill:transparent !important;
  stroke:transparent !important;
  text-shadow:none !important;
  outline-color:transparent !important;
}
/* ⚠ half the bank draws its ground in a ::before and its gloss in an ::after,
   so a plane that keeps somebody else's pseudo-element is not a plane */
.lz-off::before,.lz-off::after{opacity:0 !important}
/* an <img> or a <canvas> has no background to take away — its content IS its
   paint, so it goes on its own plane whole or not at all. ⚠ ONLY the element
   itself: a rule reaching into descendants would hide things that belong to
   another plane, which is the one thing this split may not do. */
img.lz-off,canvas.lz-off,video.lz-off{opacity:0 !important}

/* a plate: one plane of the tile, with its own thin body and its own lit edge,
   which is what makes it read as a SHEET OF GLASS rather than as a decal */
.plate{
  position:absolute; inset:0; border-radius:inherit;
  transform-style:preserve-3d;
  transform:translateZ(var(--lz, 0px));
}
/* ⚠ A PLATE'S BODY IS AN OPAQUE CARD, AND THE NEAREST ONE HIDES THE REST.
   Measured by hiding each plate and diffing with the clock stopped: plate 0
   painted NOTHING, plate 1 painted 0.00%, and plate 2 painted the entire
   widget — three planes correctly placed 250px apart in Z, and only the front
   one ever reaching the screen.

   The laminations are only ever SEEN at an edge (that is why they exist), so
   in front of the backmost plate they are RINGS: the edge survives, the middle
   is air, and you can see down through the stack. The back plate keeps a solid
   body, because something has to be the bottom of the object. */
.slab[data-layers] .plate:not(.p0) > .face{background:transparent}
.slab[data-layers] .plate:not(.p0) .sh{
  background:none;
  box-shadow:inset 0 0 0 var(--ring-w, 1.6px) var(--edge);
}
.slab[data-layers] .plate:not(.p0) .back{display:none}
.slab[data-layers] .plate:not(.p0) .rim{
  opacity:var(--plate-rim,.62);
  box-shadow:
    inset 0 1px 0 -0.2px rgba(255,255,255,.9),
    inset 0 -1px 0 -0.2px color-mix(in oklab, var(--edge), black 30%),
    inset 0 0 0 .8px color-mix(in oklab, var(--edge) 55%, transparent);
}
/* a sheet in front of the ground plate is mostly air, so its own laminations
   are a hairline and its bloom is halved — three full glows is a lamp */
.slab[data-layers] .plate:not(.p0){--ring-w:1.1px}
.slab[data-layers] > .bloom{opacity:calc(var(--bloom,0) * .55)}
/* and the slab's own back face is the bottom of the WHOLE stack, so it belongs
   behind the backmost plate rather than behind the front one */
.slab[data-layers] > .back{display:none}


/* ═══ THE DARK PLATE ═══════════════════════════════════════════════════════
   R4 is three slabs on black and the ONLY thing drawn is their rim. Over a
   pale ground an edge is read against the ground; over black there is no
   ground to read it against, so the edge has to carry its own light — a wider
   bloom, a brighter hairline, and a floor that catches some of the spill. */
body.dark .slab{--bloom:calc(var(--bloom-base, .30) * 2.1); --bloom-r:20px}
body.dark .look-glass{--bloom-base:.30}
body.dark .look-frost{--bloom-base:.14}
body.dark .look-liquid{--bloom-base:.16}
body.dark .look-chrome{--bloom-base:.22}
body.dark .look-solid{--bloom-base:.10}
body.dark .rim{
  box-shadow:
    inset 0 1.4px 0 -0.2px rgba(255,255,255,.95),
    inset 0 -1.4px 0 -0.2px color-mix(in oklab, var(--edge), white 24%),
    inset 0 0 0 1px color-mix(in oklab, var(--edge) 85%, white),
    inset 0 0 16px -5px color-mix(in oklab, var(--edge), white 30%);
}
/* the shadow on a dark floor is not a shadow, it is SPILL — the slab's own
   light landing on the ground, which is what R4's plates are standing in */
body.dark .cast{opacity:calc(var(--co, .5) * 1.5)}

/* ═══ DEPTH OF FIELD ═══════════════════════════════════════════════════════
   R7 ("Powers", "Device") is a photograph of a small object close to a lens,
   and the shallow focus is most of what says the object is REAL and near.

   ⚠ DECLARED DIVERGENCE: a `filter` flattens a preserve-3d subtree, so this
   cannot be a blur on a slab that is still meant to read as a solid. It is
   applied only past the point where the blur is wider than the object's own
   thickness — by which point there is no lamination left to see, so the
   flattening costs nothing that was visible. Under that threshold the rig
   writes `none` and the slab keeps its geometry. */
.slab{filter:var(--dof, none)}
