/* presets — a door, not a room.
 *
 * A preset names a combination of dial positions. It is applied ALONGSIDE those
 * classes, never instead of them, so every dial a preset does not pin stays
 * live after you walk through the door. See presets.js for the combinations.
 *
 * ⚠ Only boardwalk needs a rule here. The other fourteen presets are
 * pure dial compositions and declare nothing — which is the normal case and the
 * one to keep normal.
 *
 * ⚠⚠ WHY BOARDWALK IS DIFFERENT. Owner's call 2026-08-30, taken against a
 * rendered comparison kept at
 *   https://claude.ai/code/artifact/f0a142b1-f683-4d68-b82f-176ad4f6b4b2
 * It is the gallery the product showcases, and composing it from four neutral
 * grounds lost the grain, the rail's glow, the drift pace and Share Tech Mono —
 * which together are boardwalk. 44 of its 75 tokens differed. It read as a
 * different product rather than a variant. May be revisited.
 *
 * ⚠⚠ The 35 declarations below were GENERATED from the measured difference
 * between theme-boardwalk.css and `.f-bleed .m-generous .ty-mono` over base, not
 * transcribed. Regenerate rather than hand-edit if any of those change, or the
 * showcase drifts silently.
 *
 * Composition:  <html class="f-bleed m-generous ty-mono p-boardwalk">
 * ⚠ No ground class — boardwalk's paint IS its ground.
 */

.p-boardwalk {
  /* ground and ink — boardwalk's own paint, the reason it is a preset and not a composition */
  --ground:              #07060a;
  --ink:                 #e8dcc9;
  --ink-dim:             #b8ada2;
  --ink-faint:           #978d82;
  --scrim-rgb:           0 0 0;
  --scrim:               0.68;
  --lit-ground:          #0a090c;

  /* type — ⚠ PINNED. The accepted cost of keeping this gallery exact: the
     `type` dial will not change the face here. Every other dial still works. */
  --font-display:        'Share Tech Mono', 'Courier New', monospace;
  --font-label:          'Share Tech Mono', 'Courier New', monospace;
  --title-size:          11px;

  /* the rail — bespoke geometry the dials do not carry */
  --thumb-size:          78px;
  --thumb-size-sm:       54px;
  --thumb-gap:           13px;
  --thumb-gap-sm:        10px;
  --thumb-radius:        2px;
  --thumb-hover-scale:   1.07;
  --thumb-bg:            #0a0809;
  --thumb-border:        1px solid rgba(255, 255, 255, 0.16);
  --thumb-shadow:        0 8px 30px rgba(0, 0, 0, 0.65);
  --thumb-shadow-hover:  0 10px 34px rgba(0, 0, 0, 0.7);
  --thumb-filter:        brightness(0.86) saturate(0.94);
  --thumb-filter-hover:  brightness(1.12) saturate(1.06);
  --accent:              rgba(255, 214, 160, 0.75);
  --accent-glow:         rgba(255, 176, 90, 0.28);
  --n-ink:               rgba(255, 255, 255, 0.72);

  /* duotone, declared so the axis can be compared */
  --duo-dark:            #1a0d16;
  --duo-light:           #ffd9a8;

  /* environment — the grain is one of the four things a composition lost */
  --grain:               0.16;
  --grain-blend:         overlay;

  /* the enlargement */
  --enlarge-shadow:      0 30px 90px rgba(0, 0, 0, 0.8);
  --enlarge-max-w:       88vw;
  --enlarge-max-h:       86vh;
  --stage-lit-opacity:   0.07;
  --stage-lit-saturate:  0.5;

  /* drift — the plate's slow travel. Framing sets 1.05 for bleed; boardwalk runs 1.07. */
  --drift-scale:         1.07;

}

/* frieze — the ground alone, for the reason in presets.js: behind a centred
 * rail the plate rests at --backdrop, so the ground is 85% of the image and
 * sets a floor. g-dark's #171717 could not go dark enough.
 *
 * ⚠ A NEUTRAL near-black, not boardwalk's #07060a. That one is faintly warm
 * and purple, and g-dark's stated principle is "neutral charcoal, never
 * blue-black" — frieze keeps the rest of that palette, so its ground should
 * not drift off it. If an exact match to boardwalk's is wanted instead, this is
 * the single line to change.
 */
.p-frieze {
  --ground:     #080808;
  --lit-ground: #050505;
}

/* wall and paper — THE STUDY'S OWN GROUND VALUES, refining the two light
 * grounds rather than duplicating them. grounds.html tuned a wall at #f2efe8
 * with a #faf8f3 mat and a paper at #f4efe3, a few points warmer than .g-wall
 * (#f3f3f1) and .g-paper (#efece4), which the fifteen were tuned on and which
 * are left exactly as they are. The preset takes the study's numbers; the
 * dial keeps its meaning.
 *
 * ⚠ SCOPED TO THE GROUND THEY SHIP WITH — `.p-placard.g-wall`, not `.p-placard` —
 * so that turning the ground dial on either preset turns it all the way: a
 * pin that outlived its ground would paint a near-white wall under dark
 * ink the moment someone chose `dark`. frieze's pin is unconditional because
 * frieze's ground is its whole point; these are refinements, not the point. */
.p-placard.g-wall {
  --ground:     #f2efe8;
  --lit-ground: #ece9e1;
  --mount-bg:   #faf8f3;
  --thumb-bg:   #faf8f3;
  --chrome-halo: 0 1px 14px rgba(242, 239, 232, 0.92);
  --scrim-rgb:  242 239 232;
  --ink: #1c1a16; --ink-dim: #4f4a42; --ink-faint: #6d685e;
}
/* ===== flush — edge to edge, 2026-10-10 ==========================================
 *
 * ⚠⚠ THE CELL IS THE COLUMN. Every other grid draws a fixed square (`--cell-size`, 152px) centred on its wall; here
 * the size is the whole page, so grid.css's min() hands each cell the page's width shared by the columns — four
 * across, the whole width of the page, a 2px line of ground between. The SHAPE is the frame's (presets.js → `frame`,
 * grid.css → --cell-h), and the picture always fills it.
 * ⚠ AT TWO CLASSES — `.p-flush.fam-grid` — because the ground (`.g-wall`, one class, dials.css) sets the thumb's border
 * and the page's inset too, and a pin must outrank what it refines rather than win by which file was linked last.
 * ⚠ WHITE, not the wall's #f3f3f1: the reference the owner gave is a white page, and the pictures are the only
 * color on it. The inks are the wall's own, which measure darker still on white. */
.p-flush.fam-grid {
  --cell-gap:       2px;
  --cell-size:      100vw;
  --credit-inset-x: max(2.4vw, 16px);
  --thumb-border:   0;
  --thumb-radius:   0;
  --thumb-shadow:   none;
}
.p-flush.fam-grid.g-wall {
  --ground:     #ffffff;
  --lit-ground: #f7f7f6;
  --mount-bg:   #ffffff;
  --thumb-bg:   #f1f1ef;
  --chrome-halo: 0 1px 14px rgba(255, 255, 255, 0.92);
  --scrim-rgb:  255 255 255;
}
/* fewer across as the window narrows — the engine counts it (loupe.js → fillColumns, from the artist's choice); these are
   the page before the engine runs. ⚠ On a phone the works meet the screen's edges: the inset is the GRID's, never the
   page's, which the loupe mark and the portrait also stand by (the review before landing: the mark at the very edge). */
@media (max-width: 1000px) { .p-flush.fam-grid .loupe-grid { --grid-columns: 3; } }
@media (max-width: 560px)  { .p-flush.fam-grid .loupe-grid { --grid-columns: 2; --credit-inset-x: 0px; } }

/* ===== inset — flush's twin, set in from the edges, 2026-10-14 ====================
 *
 * ⚠⚠ FLUSH'S MACHINERY, ITS OWN MEASURE. The cell is the column, as flush's is — the whole page shared by the columns —
 * but the page here stands in a margin of white at each side, 6% of its width, and the pictures a 7px line of white
 * apart: both measured off the owner's screenshot (90px and 7px at 1512px wide). grid.css takes the margin out of the
 * width it shares (`--credit-inset-x`), so three across at 1512px are 439px each, as on the page he showed.
 * ⚠ The margin holds on a phone — 6% there too, about 23px at 390px, never under 16px — the point of the template is that
 * the pictures never meet the screen's edges. ⚠ Two across under 750px, before the engine runs (loupe.js → fillColumns, from the
 * template's own three). At two classes over the ground's own, as flush's. */
.p-inset.fam-grid {
  --cell-gap:       7px;
  --cell-size:      100vw;
  --credit-inset-x: max(6vw, 16px);
  --thumb-border:   0;
  --thumb-radius:   0;
  --thumb-shadow:   none;
}
.p-inset.fam-grid.g-wall {
  --ground:     #ffffff;
  --lit-ground: #f7f7f6;
  --mount-bg:   #ffffff;
  --thumb-bg:   #f1f1ef;
  --chrome-halo: 0 1px 14px rgba(255, 255, 255, 0.92);
  --scrim-rgb:  255 255 255;
}
@media (max-width: 750px) { .p-inset.fam-grid .loupe-grid { --grid-columns: 2; } }

/* ===== fieldbook — whole pictures down the page, 2026-10-12 ========================
 * ⚠ WHITE, as flush is, and for the same reason: the reference the owner gave (a picture story) is a white page with a
 * margin of it either side, and the pictures are the only color on it. At two classes, over the ground's own. */
.p-fieldbook.fam-story.g-wall {
  --ground:     #ffffff;
  --lit-ground: #f7f7f6;
  --mount-bg:   #ffffff;
  --thumb-bg:   #f1f1ef;
  --chrome-halo: 0 1px 14px rgba(255, 255, 255, 0.92);
  --scrim-rgb:  255 255 255;
}
/* …and its wide twin, the same white — its own rule, because a template's ground is read by its own name (gallery.py →
   _grounds) */
.p-overland.fam-story.g-wall {
  --ground:     #ffffff;
  --lit-ground: #f7f7f6;
  --mount-bg:   #ffffff;
  --thumb-bg:   #f1f1ef;
  --chrome-halo: 0 1px 14px rgba(255, 255, 255, 0.92);
  --scrim-rgb:  255 255 255;
}

.p-paper.g-paper {
  --ground:     #f4efe3;
  --lit-ground: #eee9dc;
  --mount-bg:   #fbf8f0;
  --thumb-bg:   #f8f4ea;
  --chrome-halo: 0 1px 14px rgba(244, 239, 227, 0.92);
  --scrim-rgb:  247 243 235;
  /* printer's red — the one spot color, on the rules and nowhere else */
  --accent: #b8352d; --accent-glow: rgba(184, 53, 45, 0.2);
  --ink: #191714; --ink-dim: #4a463f; --ink-faint: #66615a;
}

/* ===== deckle — works made OF paper, 2026-09-16 ========================
 *
 * ⚠⚠ A GRID WHOSE CELLS ARE NOT SQUARE, and that is the entire preset. Every
 * other grid in loupe is a fixed square with `object-fit: cover`, which is
 * right for photographs — the frame is the composition — and wrong for the one
 * material whose SILHOUETTE is the subject. A cut-paper work cropped square has
 * had the thing you were meant to look at removed.
 * ⚠ So the cell takes the work's own height, the picture is `contain`, and the
 * rows sit on their own baselines. The ground shows between them, which on this
 * material is the point rather than a gap.
 * ⚠ THE SHADOW GOES ON THE PICTURE, NOT THE CELL. `filter: drop-shadow` follows
 * the sheet's rectangle; `box-shadow` on the cell would draw a rectangle around
 * a cell that is now taller or shorter than its work. The value is the ground's
 * --thumb-shadow, so turning the ground turns the shadow with it.
 */
/* ⚠⚠ `.fam-grid.p-deckle`, NOT `.p-deckle`, AND THE EXTRA CLASS IS LOAD-BEARING.
 * `.fam-grid #grid > .cell { height: var(--cell) }` in loupe.css carries the
 * SAME specificity as `.p-deckle #grid > .cell` — one id, two classes — and
 * loupe.css is linked AFTER presets.css, so on a tie it wins. The result was
 * the worst kind of half-applied rule: `overflow: visible` took (nothing else
 * sets it at that weight) while `height: auto` did NOT, so every cell stayed a
 * 152px square while its picture kept its natural height and hung out of the
 * bottom into the row below. The owner, 2026-09-16: "should they be
 * overlapping in deckle?"
 * ⚠ Raising the selector rather than reordering the links: the link order is
 * deliberate and documented (framing must beat ground), and `!important` would
 * put this rule beyond the reach of the build-mode dials that are coming. */
.fam-grid.p-deckle :is(#grid, .loupe-grid) { align-items: start; }
.fam-grid.p-deckle :is(#grid, .loupe-grid) > .cell {
  height: auto;
  /* ⚠⚠ AND A FLOOR, OR NOTHING EVER LOADS. A cell whose height comes from its
     picture is 0px tall until the picture arrives — and the picture carries
     `loading="lazy"`, which does not fire for a box of zero area. So the cell
     waits for the image, the image waits for the cell, and the page stays empty
     ground. `min-height` breaks the deadlock with the one number already in
     hand: a cell is at least as tall as it is wide until its own work says
     otherwise. ⚠ Anything else that sizes a cell from its content has to think
     about this; it is a property of lazy loading, not of this preset. */
  min-height: var(--cell);
  width: var(--cell);
  background: transparent;
  border: 0;
  box-shadow: none;
  overflow: visible;
}
.fam-grid.p-deckle :is(#grid, .loupe-grid) > .cell img {
  height: auto;
  object-fit: contain;
  /* ⚠ THROUGH THE GROUND'S TOKEN, so turning the ground turns the shadow with
     it. `--thumb-shadow` has no spread, which is the one thing drop-shadow()
     cannot take — a spread added to that token later would silently drop this
     filter and the layers would flatten with nothing said. */
  filter: var(--thumb-filter, none) drop-shadow(var(--thumb-shadow, 0 10px 22px rgba(46, 39, 30, 0.3)));
}
