/* ==========================================================================
   work-grid.css — the work page's infinite card field.

   THE PAGE IS BLACK NOW. It was the light gradient the wheel sat on; Figma
   14584:12146 is a dark field, so the ground and the grain both move to the
   treatment the home page already has — the grain's `overlay` does nothing
   against black, so it has to lift instead.

   THE BAR DOES NOT MOVE WITH THEM, and that is deliberate. It is #393939 on
   every page and every section: it is the one element present everywhere, so
   it is the site's constant and cannot change identity halfway round.

   EVERY MEASUREMENT HERE IS FIGMA'S, at its 1920 frame:

     cell         475 x 331
     pitch        491 x 363   (16px between columns, 32px between rows)
     plate        475 x 311
     image        inset 32     -> 411 x 247, which is 5:3
     ticks        3 x 3 at the plate's four corners
     microtype    5px tall, 15px under the plate

   They are held as custom properties rather than numbers in rules, because
   js/work-grid.js needs the same values to lay the field out, and two copies of
   a pitch is a grid that drifts apart by one gutter every screen.
   ========================================================================== */

body[data-page="design"]{
  --about-ground: #000000;
  --about-ink:    #C8C8C8;
  --about-dim:    rgba(200,200,200,.5);
  background: var(--about-ground);
  color: var(--about-ink);
}

/* The lifted grain the black home page uses. The BAR is deliberately not
   touched: #393939 on every page and every section, which is ui.css's default
   — see the note in css/about.css where the old inversion was removed. */
body[data-page="design"] .grain{
  --grain-blend: lighten;
  --grain-opacity: .06;
  --grain-brightness: 100%;
  --grain-contrast: 50%;
  --grain-size: 1em;
}

/* ---------------- the field ------------------------------------------------
   TOUCH-ACTION AND OVERSCROLL ARE NOT STYLING, they are the brief. "Turn off
   the gestures for that page so a user does not accidentally change the page"
   is three separate browser behaviours, and only one of them can be stopped
   from JavaScript:

     touch-action: none        stops the browser claiming the gesture for its
                               own panning before a single event is delivered
     overscroll-behavior: none stops the two-finger swipe that navigates back,
                               and stops a scroll chaining out to the document
     the third is preventDefault on a NON-PASSIVE wheel listener, which
     js/work-grid.js does — CSS cannot do that one.

   All three are needed. Any two of them still leave a trackpad able to take
   the visitor off the page mid-drag. */
.wgrid{
  position: fixed;
  inset: 0;
  overflow: hidden;
  background: var(--about-ground);
  touch-action: none;
  overscroll-behavior: none;
  cursor: grab;
  /* The cell, as Figma draws it. js/work-grid.js reads these back rather than
     carrying its own copy — see the note at the top. */
  --cell-w: 475px;
  --cell-h: 331px;
  --pitch-x: 491px;
  --pitch-y: 363px;
  --plate-h: 311px;
  --inset: 32px;
}
.wgrid.is-dragging{ cursor: grabbing; }

/* The filter's host. Zero-sized and out of flow — it exists only to own the
   <filter> the photographs reference; nothing about it is ever painted. */
.wgrid__defs{ position: absolute; width: 0; height: 0; overflow: hidden; }

/* THE FIELD'S ONE LAYER. The photographs were a WebGL canvas under this until
   the SecurityError in js/work-grid.js's header settled the argument — they are
   plain <img> now, inside the same cells that carry the ticks and the type, so
   there is nothing left that could drift out of step with anything else. */
.wgrid__world{
  position: absolute; left: 0; top: 0;
  width: 100%; height: 100%;
  z-index: 1;
  pointer-events: none;
  will-change: transform;
}

.wgrid__cell{
  position: absolute; left: 0; top: 0;
  width: var(--cell-w);
  height: var(--cell-h);
  will-change: transform, opacity;
  /* THE TOP-LEFT CORNER, NOT THE MIDDLE, and this is a correctness fix rather
     than a preference.

     js/work-grid.js writes `translate3d(top-left) scale(s)`, which is only what
     it reads as when the scale happens about the origin the translate targeted.
     At the browser's default 50% 50% the element is translated and THEN scaled
     about its own centre, so the card lands at
     `translate + cardW/2 * (1 - s)` — a displacement that is zero only while s
     is exactly 1. It was not: with the zoom at 2.5 every card sat some hundreds
     of px from where the code believed it was, uniformly, so the field looked
     correct and the DWELL TEST was picking the wrong card, because that test is
     the one thing that compares the pointer with those believed positions.

     The projective placement needs it too: that matrix maps the card's own
     local coordinates straight to screen coordinates, which is only true from
     the element's corner. */
  transform-origin: 0 0;
  /* THE FOCUS DIM RIDES HERE, on the cell — so the photograph, its ticks and
     its label fade as one object rather than three that happen to agree. */
  transition: opacity var(--focus-ms, 420ms) ease;
}

/* THE CONTAINER THE PICTURE LIES IN — #393939, and it is Figma's Frame 5587:
   the full 475 x 311 plate, with the photograph inset 32px inside it. It was
   nothing at all before, so the picture floated on the page's black and the
   card had no body; this is the card.

   The same #393939 as the bar, which is not a coincidence — it is the site's
   one furniture colour, and the plate is furniture.

   IT IS ALSO WHAT YOU SEE BEFORE A PHOTOGRAPH ARRIVES. Thirty images decode at
   their own pace and a plate with no ground shows the page through the hole
   until they do, which reads as a missing card rather than a loading one. */
.wgrid__plate{
  position: absolute;
  left: 0; top: 0;
  width: var(--cell-w);
  height: var(--plate-h);
  background: var(--plate-bg, #393939);
  overflow: hidden;
  /* HOW ROUNDED IT IS WHILE MOVING. One variable on the root, because movement
     is global and every card rounds by the same amount at the same moment —
     thirty inline writes would all be carrying the same number. */
  border-radius: var(--card-radius, 0px);
  will-change: transform, filter;
}
/* The photograph: Figma insets it 32px, so 411 x 247 — a 5:3 window that
   object-fit fills with the middle of whatever it is given. The set is mixed
   portrait and landscape and every one of them has to sit in that rectangle. */
.wgrid__plate img{
  position: absolute;
  left: var(--inset); top: var(--inset);
  width: calc(var(--cell-w) - var(--inset) * 2);
  height: calc(var(--plate-h) - var(--inset) * 2);
  object-fit: var(--img-fit, cover);
  border-radius: inherit;
  /* The crop, about the window's own centre. The plate's overflow:hidden is
     what clips it, so scaling up shows less of the photograph rather than
     spilling it over the container. */
  transform: scale(var(--img-zoom, 1));
  /* The drag belongs to the root. An image that can be picked up is an image
     that starts a native drag-and-drop the moment you try to move the field. */
  pointer-events: none;
  user-select: none;
  -webkit-user-drag: none;
}

/* THE GREY COPY, stacked exactly on the colour one. Its filter is CONSTANT —
   that is the whole point: a constant filter is rasterised once and thereafter
   only composited, where a filter whose value changes forces the element to be
   filtered again every time. js/work-grid.js cross-fades this with `opacity`,
   which the compositor handles without touching a pixel of either layer.

   It inherits every geometric rule from the img rule above, so the two are
   guaranteed to sit on top of one another; only the filter and the fade are
   its own. */
.wgrid__plate .wgrid__grey{
  filter: grayscale(1);
  opacity: 0;
}

/* The four corner ticks. 3x3 at the plate's corners, and they are the thing
   that BRIGHTENS on focus rather than a border appearing — Figma's focus state
   changes weight, not shape. */
.wgrid__tick{
  position: absolute;
  width: 3px; height: 3px;
  background: var(--about-dim);
  transition: background var(--focus-ms, 420ms) ease;
}
.wgrid__tick--tl{ left: 0; top: 0; }
.wgrid__tick--tr{ right: 0; top: 0; }
.wgrid__tick--bl{ left: 0; top: var(--plate-h); transform: translateY(-3px); }
.wgrid__tick--br{ right: 0; top: var(--plate-h); transform: translateY(-3px); }
.wgrid__cell.is-focus .wgrid__tick{ background: #FFFFFF; }

/* The label strip: 5px tall, 15px under the plate, one cluster hard against
   each edge. Figma's own 30px and 35px widths are not set here — the type sets
   them, and pinning both would fight the font. */
.wgrid__meta{
  position: absolute;
  left: 0; right: 0;
  top: calc(var(--plate-h) + 15px);
  height: 5px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 5px;
  line-height: 1;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--about-dim);
  white-space: nowrap;
  transition: color var(--focus-ms, 420ms) ease;
}
.wgrid__cell.is-focus .wgrid__meta{ color: #FFFFFF; }
.wgrid__meta span{ opacity: .6; }
.wgrid__cell.is-focus .wgrid__meta span{ opacity: 1; }

/* SCROLL, bottom right, 15px above the bar — Figma has it at y=1037 on a 1080
   frame with a 28px bar, which is 15px of clearance. */
.wgrid__scroll{
  position: fixed;
  right: 10px;
  bottom: 43px;
  z-index: 40;
  font-size: 5px;
  line-height: 1;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--about-dim);
  pointer-events: none;
}

/* THE BLOB, the home page's block-01 one, hosted here. z-index 0 puts it UNDER
   the cards, which is where it sits on every other page that carries it — it is
   the ground the work floats over, not a wash across it. */
body[data-page="design"] .work-blobs{ z-index: 0; }

@media (prefers-reduced-motion: reduce){
  .wgrid__cell,
  .wgrid__tick,
  .wgrid__meta{ transition: none; }
}

