/* FOGRIO INTERNATIONAL — the house stylesheet.
   Brand layer is black and white [SALMAN, 2026-08-25]. The vestments carry the only colour.

   ⛔ The grammar this deliberately does NOT use, because Salman rejected it by name as
      "a site that AI would make":
        muted neutral ground + one near-black band + brown metallic accent
        eyebrow -> headline pun -> lede -> primary CTA -> secondary CTA
        split hero with copy left and a product floating right
        alternating full-width bands
        Roman-numeral eyebrows, decorative tracked small caps everywhere
   The organising idea instead is a REGISTER: a maker's catalogue, set as an index,
   information dense and stated plainly. A house that makes things, not a landing page. */

:root{
  --black:#000000;
  --ink:#0B0B0C;
  --ink-2:#16171A;
  --metal:#C8CBCE;
  --grey:#6E7175;
  --paper:#F4F3F1;
  --white:#FFFFFF;
  --rule-dark:#26282B;
  --rule-light:#D8D6D2;

  --sans:Futura,"Futura PT","Century Gothic","Avenir Next",Avenir,"Segoe UI",system-ui,sans-serif;

  --edge:clamp(20px,3.2vw,52px);
  --gap:clamp(28px,3.4vw,56px);
  --measure:62ch;
}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--sans);
  font-size:clamp(15px,1.02vw,17px);
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
img{max-width:100%;display:block}

a{color:inherit}
:focus-visible{outline:1px solid currentColor;outline-offset:6px}

/* ---------------------------------------------------------------- masthead */
.masthead{
  position:sticky;
  top:0;
  z-index:20;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:var(--gap);
  padding:clamp(14px,1.5vw,20px) var(--edge);
  background:var(--black);
  color:var(--paper);
  border-bottom:1px solid var(--rule-dark);
}
.masthead .wm{width:clamp(112px,11vw,164px);color:var(--paper);flex:0 0 auto}
.masthead .wm svg{display:block;width:100%;height:auto}
.masthead nav{display:flex;gap:clamp(14px,2.1vw,34px);flex-wrap:wrap;justify-content:flex-end}
.masthead nav a{
  text-decoration:none;
  font-size:clamp(10px,0.76vw,12px);
  letter-spacing:.18em;
  text-transform:uppercase;
  opacity:.84;
  padding-bottom:2px;
  border-bottom:1px solid transparent;
}
.masthead nav a:hover,.masthead nav a[aria-current="page"]{opacity:1;border-bottom-color:currentColor}

/* ---------------------------------------------------------------- opening */
.opening{
  position:relative;
  height:100svh;
  min-height:520px;
  overflow:hidden;
  background:var(--black);
}
.opening .room{
  position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;object-position:50% 50%;
}
.opening .mark{
  position:absolute;left:var(--edge);bottom:clamp(104px,14.5vh,168px);
  width:min(560px,44vw);margin:0;color:var(--paper);z-index:3;
}
.opening .mark svg{display:block;width:100%;height:auto}
.opening .place{
  position:absolute;left:var(--edge);bottom:clamp(64px,9vh,104px);z-index:3;
  margin:0;font-size:clamp(10px,0.74vw,12px);letter-spacing:.22em;
  text-transform:uppercase;color:var(--metal);
}
/* ⛔ This was `right:var(--edge)` with `mix-blend-mode:difference`, and looking at the render
   killed it. Difference blending returns |backdrop - white|, so over a MID-TONE backdrop it
   returns a mid tone and the text disappears into the photograph. The light spill on the right
   of the room is exactly that mid tone, and the R of ENTER had already vanished into it.
   A blend mode makes legibility a function of whatever picture is behind it, and the picture
   changes. So: no blend, plain paper on the floor's darkness, under the mark where the reading
   order already goes. */
.opening .enter{
  position:absolute;left:var(--edge);bottom:clamp(30px,4.6vh,54px);z-index:3;
  color:var(--paper);text-decoration:none;
  font-size:clamp(10px,0.74vw,12px);letter-spacing:.22em;text-transform:uppercase;
  display:inline-flex;align-items:center;gap:12px;
}
.opening .enter .rule{
  display:block;width:clamp(28px,3.4vw,54px);height:1px;background:currentColor;
  transition:width .38s cubic-bezier(.2,.7,.2,1);
}
.opening .enter:hover .rule{width:clamp(46px,5.6vw,84px)}

/* ---------------------------------------------------------------- opening, four stoles
   [SALMAN] 2026-09-25 asked for the four stoles together. Four figures fill the frame, so there
   is NO dark space for the wordmark (a reviewer scanned every 560x103 window of the 1440 render:
   none was dark). Three layouts were measured before this one:
   1. mark on the photo: it sat on the green and red fringe and washed out on the white albs;
   2. photo cropped to a shorter box: the collars were cut, so the stoles read as bands on cloth;
   3. that box plus a band: read as a letterbox, and 1366x768 clipped the fringe tips.
   So: the WHOLE photograph always shows, collar to floor, never cropped, set on the black page
   with its side edges fading into black. Beneath it, a title band: mark left, place and ENTER
   right. Scoped to .opening--four; the approved r9 opening is untouched. */
@media (min-width:761px){
  .opening.opening--four .roomwrap{bottom:160px}
  .opening.opening--four .room{
    left:50%;right:auto;width:auto;max-width:100%;height:100%;transform:translateX(-50%);
    object-fit:contain;object-position:50% 0%;
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 7%,#000 93%,transparent 100%),
                       linear-gradient(to bottom,#000 88%,transparent 100%);
    -webkit-mask-composite:source-in;
            mask-image:linear-gradient(to right,transparent 0,#000 7%,#000 93%,transparent 100%),
                       linear-gradient(to bottom,#000 88%,transparent 100%);
            mask-composite:intersect;
  }
  .opening--four .mark{width:min(440px,32vw);bottom:38px}
  .opening--four .place{left:auto;right:var(--edge);bottom:84px;text-align:right;font-size:12px}
  .opening--four .enter{left:auto;right:var(--edge);bottom:44px;font-size:12px}
}
@media (max-width:760px){
  /* PHONE: the same window of the photograph on EVERY phone, set by width, not by the box.
     A zoom on a cover-fitted box failed: the visible slice depends on each phone's aspect, so
     390x844 showed purple and 360/375 showed green AND purple (measured). Here the image is sized
     from 100vw so the window is always source x 428-948 (the whole red figure, no neighbour's
     stole) and rows 40-840 (collar to below the fringe). The box takes exactly that height; a
     short phone scrolls a little rather than losing the fringe. */
  /* --ph is the photo's height: the full-width height, OR on a short phone the height left after
     the header and the ENTER row (reviewer, round 6: 375x667 and 360x640 cut the stole at the
     flames). When height is the limit the window stays x 428-948 and the photo is centred with
     thin black margins, so no neighbour's stole comes in. Everything below scales from --ph. */
  /* min-height 100svh: on short phones the NEXT section's FOGRIO heading was showing, cut in
     half, at the foot of the first screen (reviewer, round 7). The opening owns the whole screen. */
  .opening.opening--four{--ph:min(calc(100vw * 800 / 520), calc(100svh - 236px));height:auto;min-height:100svh}
  .opening.opening--four .roomwrap{position:relative;height:var(--ph);width:calc(var(--ph) * 520 / 800);
    max-width:100%;margin:0 auto;overflow:hidden;
    /* the side edges fade into black like desktop; hard edges sliced the neighbours' hands and
       read as a crop error. A short bottom fade softens the line just under the fringe. */
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 26px,#000 calc(100% - 26px),transparent 100%),
                       linear-gradient(to bottom,#000 calc(100% - 16px),transparent 100%);
    -webkit-mask-composite:source-in;
            mask-image:linear-gradient(to right,transparent 0,#000 26px,#000 calc(100% - 26px),transparent 100%),
                       linear-gradient(to bottom,#000 calc(100% - 16px),transparent 100%);
            mask-composite:intersect}
  .opening.opening--four .room{
    position:absolute;inset:auto;top:calc(var(--ph) * -40 / 800);left:calc(var(--ph) * -428 / 800);
    width:calc(var(--ph) * 1671 / 800);height:auto;max-width:none;object-fit:fill;transform:none;
  }
  /* ENTER below the photograph, on black: on the photo it touched the red fringe. */
  .opening--four .enter{position:static;margin:16px var(--edge) 26px}
}

/* ---------------------------------------------------------------- opening, the room (D2), phone
   Desktop is r9's own layout, untouched. On a phone the r9 cover-crop centres the red figure and
   cut the hanging stoles at the screen edge: half the purple on 390x844, slivers of ivory on 360
   and 320 (measured in the render). A stole sliced by the frame reads as a mistake, and the room
   is too wide to show all three hanging stoles at a readable size. So a phone gets a fixed window
   of the photograph, set by width exactly like .opening--four: source x 600-1116 (the whole red
   figure, no hanging stole; purple ends at x 596, ivory starts at 1120) and rows 0-880 (collar to
   below the fringe). [ASSUMED, DECISIONS 2026-09-25e] on a phone D2 shows the red figure alone. */
/* ⛔ NOT the --ph reserve of .opening--four: a fixed 236px allowance for the header failed at
     760x1024, where the wordmark is larger and ENTER fell 11px below the first screen (measured).
     Instead the opening is a three-row grid (header, photograph, ENTER) at 100svh, and the photo
     box takes whatever height the middle row has, at the window's own aspect, capped at the
     full-width height. Nothing is reserved by guesswork, so it holds at any size. */
@media (max-width:760px){
  /* min-height:0: the base .opening keeps a 520px floor, which on a landscape phone (667x375)
     pushed ENTER off the first screen (Codex review 2026-09-25). */
  .opening.opening--room{grid-template-rows:auto minmax(0,1fr) auto;min-height:0}
  .opening.opening--room .roomwrap{position:relative;height:100%;max-height:calc(100vw * 880 / 516);
    width:auto;max-width:100%;aspect-ratio:516 / 880;justify-self:center;align-self:center;overflow:hidden;
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 18px,#000 calc(100% - 18px),transparent 100%),
                       linear-gradient(to bottom,#000 calc(100% - 16px),transparent 100%);
    -webkit-mask-composite:source-in;
            mask-image:linear-gradient(to right,transparent 0,#000 18px,#000 calc(100% - 18px),transparent 100%),
                       linear-gradient(to bottom,#000 calc(100% - 16px),transparent 100%);
            mask-composite:intersect}
  .opening.opening--room .room{
    position:absolute;inset:auto;top:0;left:calc(100% * -600 / 516);
    width:calc(100% * 1672 / 516);height:auto;max-width:none;object-fit:fill;transform:none;
  }
  .opening--room .enter{position:static;margin:16px var(--edge) 26px}
}

/* ---------------------------------------------------------------- opening, the rotating mannequins
   [SALMAN] 2026-09-25: four mannequins, "whichever the mouse points, it comes on front and even on
   its own, it circles to switch"; then "lets get creative, i give you and codex the creative role".
   Concept (Codex + Claude, FOGRIO.md 14h): a near-black atelier keeping A's window beam and hanging
   albs, the albs falling into shadow, the stoles lit, the front figure dominant.
   THE STAGE is the room photograph's own 1672x941 space, sized to COVER the opening like the
   approved photograph (container units), so a figure placed at a foot point in source pixels stands
   on the same floor at every window size. Figures carry their spot as custom properties set by
   carousel.js (and baked into the HTML, so the rest composition renders without script).
   Travel: left and top ease differently, so a figure moving between spots follows a curve, not a
   straight slide; this is what makes four spots read as a ring turning. */
/* touch-action pan-y: vertical scrolling stays the browser's, horizontal swipes come to the page.
   Without it the browser claims a sideways drag and cancels it, and the swipe never turned the ring
   (caught by check_carousel.js, 2026-09-25). */
.opening--carousel{background:#050505;touch-action:pan-y}
/* the stage's container: the whole opening on a desktop, the middle row on a phone */
.opening--carousel .stagebox{position:absolute;inset:0;container-type:size;overflow:hidden}
/* ⛔ FITTED, NOT COVERED (Codex review of engine 2): covering the screen cropped whatever the screen's
   shape cut away: the wings on a 768x1024 tablet, the front collar on a 1440x600 window. The stage is
   sized so the ring's whole window (1440 source px wide, the room's full height) always fits, which on
   a usual desktop IS a cover (1440x900 gives 1599px, as before), and on a short or very wide window
   leaves soft black margins instead of a lost collar. The edges fade, so a margin reads as shadow. */
.opening--carousel .stage{position:absolute;left:50%;top:50%;
  width:min(calc(100cqw * 1672 / 1440),calc(100cqh * 1672 / 941));aspect-ratio:1672 / 941;transform:translate(-50%,-50%);
  -webkit-mask-image:linear-gradient(to right,transparent,#000 2.5%,#000 97.5%,transparent),
                     linear-gradient(transparent,#000 2.5%,#000 97.5%,transparent);
  -webkit-mask-composite:source-in;
          mask-image:linear-gradient(to right,transparent,#000 2.5%,#000 97.5%,transparent),
                     linear-gradient(transparent,#000 2.5%,#000 97.5%,transparent);
          mask-composite:intersect}
.opening--carousel .camera{position:absolute;inset:0;transform-origin:0 0}
.opening--carousel .veil{position:absolute;inset:-20%;background:#030303;opacity:0;pointer-events:none;z-index:9}
.opening--carousel .plate{position:absolute;inset:0;width:100%;height:100%;display:block;will-change:transform}
/* the ring, the floor light, the dust and the near layer all live in the stage's own coordinates */
.opening--carousel .ring{position:absolute;inset:0;will-change:transform}
.opening--carousel .dust{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
.opening--carousel .fg{position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none;
  z-index:5;will-change:transform}
/* ENGINE 2 (2026-09-26): figures are placed by carousel.js with transforms only, every frame, on one
   continuous ring path; nothing here transitions position. The rest pose is baked into the page per
   colour (build.py), so the first paint is already right. */
.opening--carousel .fig{position:absolute;left:0;top:0;width:calc(var(--w) * 1%);
  transform-origin:var(--ox) var(--oy);will-change:transform;
  margin:0;padding:0;border:0;background:none;pointer-events:none;-webkit-tap-highlight-color:transparent}
.opening--carousel .fig img{display:block;width:100%;height:auto;user-select:none;-webkit-user-drag:none}
.opening--carousel .fig .robe-shade,.opening--carousel .fig .stole,.opening--carousel .fig .stole-shade,
.opening--carousel .fig .glint{position:absolute;left:0;top:0}
/* depth shading by OPACITY (Codex, 2026-09-26: never animate brightness filters): a static black copy
   of each layer lies over it and its opacity is the darkness, so each frame only changes an opacity,
   which the browser composites without repainting. robe-shade darkens the whole figure, the stole on
   top escapes it, and stole-shade darkens the stole by its own, smaller amount. */
.opening--carousel .fig .robe-shade,.opening--carousel .fig .stole-shade{filter:brightness(0)}
.opening--carousel .fig .robe-shade{opacity:var(--rs)}
.opening--carousel .fig .stole-shade{opacity:var(--ss)}
/* the reward on arrival: one sweep of light across the stole, drawn as a brighter copy of the stole
   seen only through a moving gradient band (a gradient mask, so it works from a local file too) */
/* tuned by eye on frozen frames: at brightness 1.75 and a wide band the sweep washed the ivory panel
   to white like a blown-out photograph; a gentle lift with a little saturation, in a narrow soft band
   at a steady speed, reads as a sheen crossing the cloth and embroidery */
/* the sweep lights ONLY the embroidered thread and the fringe (thread-c.png), so it reveals the
   craftsmanship and leaves the plain cloth quiet (Codex's art note, 2026-09-26) */
.opening--carousel .fig .glint{opacity:0;filter:brightness(1.55) saturate(1.2);
  -webkit-mask-image:linear-gradient(104deg,transparent 45%,rgba(0,0,0,.9) 50%,transparent 55%);
          mask-image:linear-gradient(104deg,transparent 45%,rgba(0,0,0,.9) 50%,transparent 55%);
  -webkit-mask-size:320% 100%;mask-size:320% 100%;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:100% 0;mask-position:100% 0}
.opening--carousel .fig.is-arriving .glint{animation:fog-glint 1.15s cubic-bezier(.45,.05,.55,.95) both}
@keyframes fog-glint{0%{opacity:0;-webkit-mask-position:78% 0;mask-position:78% 0}
  20%{opacity:.9}80%{opacity:.9}100%{opacity:0;-webkit-mask-position:22% 0;mask-position:22% 0}}
/* the floor light under the front spot; it swells as a stole arrives */
/* size from Codex's light map (light.json front_floor_spotlight); brighter than its suggested 0.04 so
   the swell on arrival is felt, still a soft pool, never a disc */
.opening--carousel .pool{position:absolute;width:var(--pw);height:var(--ph);transform:translate(-50%,-50%);
  pointer-events:none;background:radial-gradient(closest-side,rgba(255,248,236,.2),rgba(255,248,236,.07) 55%,rgba(255,248,236,0));
  mix-blend-mode:screen;opacity:.55}
.opening--carousel .pool.is-swelling{animation:fog-pool 1.25s cubic-bezier(.3,.1,.2,1) both}
@keyframes fog-pool{0%{opacity:.55;transform:translate(-50%,-50%) scale(1)}
  32%{opacity:1;transform:translate(-50%,-50%) scale(1.14)}100%{opacity:.55;transform:translate(-50%,-50%) scale(1)}}
.opening--carousel .stagebox{cursor:grab}
.opening--carousel.is-dragging .stagebox,.opening--carousel.is-dragging .hit{cursor:grabbing}
.opening--carousel .fig .shadow{position:absolute;left:var(--shl);top:var(--sht);width:var(--shw);height:var(--shh);
  background:radial-gradient(closest-side,rgba(0,0,0,.72),rgba(0,0,0,0));transform:translate(-50%,-50%)}
.opening--carousel .fig .hit{position:absolute;left:var(--hl);top:var(--ht);width:var(--hw);height:var(--hh);
  pointer-events:auto;cursor:pointer}
.opening--carousel .fig[aria-pressed="true"] .hit{cursor:default}
.opening--carousel .fig:focus{outline:none}
.opening--carousel .fig:focus-visible .hit{outline:1px solid rgba(255,255,255,.55);outline-offset:4px}
.opening--carousel .season{position:absolute;left:50%;bottom:clamp(26px,4.2vh,48px);transform:translateX(-50%);
  z-index:6;margin:0;color:var(--paper);font-size:clamp(10px,0.74vw,12px);letter-spacing:.22em;
  text-transform:uppercase;white-space:nowrap;color:var(--metal);transition:opacity .28s ease,transform .38s cubic-bezier(.2,.8,.2,1)}
/* the caption fades out as a turn starts and back in with the new stole's name at mid-turn, so it
   never names a stole that is not yet in front (Codex review 1) */
.opening--carousel .season{will-change:opacity,transform}
.opening--carousel .season.is-swapping{opacity:0;transform:translateY(6px);transition-duration:.14s}
/* two lines: the stole in paper, its season beneath in the quieter metal tone */
.opening--carousel .season b{display:block;font-weight:400;color:var(--paper);font-size:1.18em;
  letter-spacing:.24em;margin-bottom:.55em}
.opening--carousel .mark,.opening--carousel .place,.opening--carousel .enter{z-index:7}
/* The approved bottom-left wordmark would sit across the left wing's stole, so the brand block runs
   along the dark floor under the figures: FOGRIO and the place bottom-left, the season of the front
   stole and ENTER bottom-right, the hero between them. */
@media (min-width:761px){
  .opening--carousel .mark{bottom:clamp(66px,9vh,96px);width:min(330px,23vw)}
  .opening--carousel .place{bottom:clamp(36px,5vh,56px)}
  .opening--carousel .season{left:auto;right:var(--edge);transform:none;bottom:clamp(74px,10vh,106px);text-align:right}
  .opening--carousel .enter{left:auto;right:var(--edge);bottom:clamp(34px,4.8vh,54px)}
}
/* PHONE: three rows, header / stage / caption and ENTER, at the screen's own height. The stage is
   sized to CONTAIN a 760px-wide, full-height slice of the room inside the middle row, so the header
   never covers a collar and nothing overflows on a short or landscape phone. (The first version sized
   the stage from width alone under a translucent header: Codex measured the front stole running off
   both edges at 667x375 and the collar under the header at 760x1024.) */
/* ⛔ BY SHAPE AGAIN (Codex review of engine 2): the rows also serve any screen more portrait than 6:5,
   such as a tablet held upright, where the desktop ring cannot fit side by side. Above 760px the shared
   phone rules do not apply, so this block states everything itself. */
@media (max-width:760px), (max-aspect-ratio:6/5){
  .opening.opening--carousel{display:flex;flex-direction:column;height:100svh;min-height:0}
  .opening.opening--carousel .plate-head{display:block;position:relative;order:-1;flex:0 0 auto;z-index:7;
    background:#050505;padding:clamp(44px,7vh,68px) var(--edge) clamp(20px,3vh,30px)}
  .opening.opening--carousel .place{position:static;margin-top:clamp(12px,2vh,18px);font-size:11px;letter-spacing:.2em}
  /* .opening.opening--carousel: the shared phone rule for .opening .mark comes later in this file and
     won at equal specificity, making the name 430px wide on a 375px-tall landscape phone */
  /* position:static too: above 760px the desktop rule keeps the mark absolute, and on a 768x1024
     tablet it sat 38px above the screen (Codex, engine 2 review 2) */
  .opening.opening--carousel .mark{position:static;width:min(430px,86vw,calc(11svh * 651 / 120))}
  .opening.opening--carousel .stagebox{position:relative;inset:auto;flex:1 1 0;min-height:0}
  .opening--carousel .stage{width:min(calc(100cqw * 1672 / 760),calc(100cqh * 1672 / 941));
    -webkit-mask-image:linear-gradient(transparent,#000 10%,#000 90%,transparent);
            mask-image:linear-gradient(transparent,#000 10%,#000 90%,transparent)}
  /* min-height fits the longest caption (the red stole's occasions wrap to two lines on a 320px
     phone): a caption that changed height mid-turn resized the room row and every figure with it,
     by about 5% (Codex review 2) */
  .opening.opening--carousel .season{position:static;transform:none;flex:0 0 auto;margin:10px var(--edge) 0;
    text-align:left;white-space:normal;font-size:10px;letter-spacing:.18em;line-height:1.5;min-height:5.6em}
  .opening.opening--carousel .enter{position:static;flex:0 0 auto;margin:14px var(--edge) clamp(14px,3svh,26px)}
}

/* SHORT LANDSCAPE SCREENS (a phone on its side, any width): rows left the room a 150px strip at
   667x375, and at 844x390 the desktop layout's 520px floor cut the stoles off below the screen
   (render; Codex review 2). So by SHAPE, not width: the name, caption and ENTER stack in a column on
   the left and the room takes the full height on the right, framed like the portrait phone. */
@media (orientation:landscape) and (max-height:540px){
  .opening.opening--carousel{display:grid;grid-template-columns:minmax(0,36%) minmax(0,1fr);
    grid-template-rows:minmax(0,1fr) auto auto;height:100svh;min-height:0}
  .opening.opening--carousel .plate-head{display:block;position:relative;grid-column:1;grid-row:1;
    align-self:end;background:none;padding:0 var(--edge) 14px;order:0}
  .opening.opening--carousel .mark{position:static;width:min(92%,220px)}
  .opening.opening--carousel .place{position:static;margin-top:10px;font-size:11px;letter-spacing:.2em}
  .opening.opening--carousel .season{position:static;grid-column:1;grid-row:2;margin:0 var(--edge);
    transform:none;text-align:left;white-space:normal;font-size:10px;letter-spacing:.18em;line-height:1.5;
    min-height:5.6em}
  .opening.opening--carousel .enter{position:static;grid-column:1;grid-row:3;margin:14px var(--edge) 18px}
  .opening.opening--carousel .stagebox{position:relative;inset:auto;grid-column:2;grid-row:1 / 4;height:100%;
    -webkit-mask-image:linear-gradient(to right,transparent 0,#000 44px);
            mask-image:linear-gradient(to right,transparent 0,#000 44px)}
  .opening.opening--carousel .stage{width:min(calc(100cqw * 1672 / 760),calc(100cqh * 1672 / 941));
    -webkit-mask-image:linear-gradient(transparent,#000 10%,#000 90%,transparent);
            mask-image:linear-gradient(transparent,#000 10%,#000 90%,transparent)}
}

/* ---------------------------------------------------------------- the two directions to be EXPERIENCED
   [SALMAN] 2026-09-26: "i dont wanna reject any without experiencing". Both keep the figures still:
   A (camera.js) moves the camera and the light; B (reveal.js) changes the stage in darkness. */
.opening--camera .fig .robe-shade,.opening--camera .fig .stole-shade,
.opening--reveal .fig .robe-shade,.opening--reveal .fig .stole-shade{transition:opacity 1.1s cubic-bezier(.4,0,.2,1)}
.opening--camera .camera{will-change:transform}
/* soft focus on the ones the camera leaves, a little, so depth reads as a lens rather than a blur effect */
.opening--camera .fig{transition:filter 1.2s cubic-bezier(.4,0,.2,1)}
.opening--camera .fig.is-away{filter:blur(1.6px)}
.opening--camera .pool,.opening--reveal .pool{transition:left 1.6s cubic-bezier(.65,0,.35,1),top 1.6s cubic-bezier(.65,0,.35,1)}
.opening--camera .fig .hit,.opening--reveal .fig .hit{cursor:pointer}
/* [SALMAN] 2026-09-26 (DECISIONS 09-26i): each stole on the camera page is a LINK to its listing. The
   hand cursor shows at once over the whole figure, before the camera moves, so the click promise reads
   first (Codex's cue); pointing still steers the camera. */
.opening--camera .fig{text-decoration:none;color:inherit}
.opening--camera .fig:focus-visible .hit{outline:1px solid rgba(255,255,255,.55);outline-offset:4px}
/* the caption names the stole in view and is its link; "View the stole" joins it once the camera is there */
/* Codex's caption (2026-09-26: "small, faint captions make essential information feel secondary"):
   the stole's name 16 px bold in warm white, its season 12 px beneath, and the action in sentence case,
   white, underlined, with a 44 px target, over a soft local shade so it holds on any part of the room */
.opening--camera .season{text-decoration:none;cursor:pointer;font-size:12px;font-weight:500;line-height:18px;
  letter-spacing:.14em;color:#D6D2CC}
.opening--camera .season b{font-size:16px;font-weight:600;line-height:22px;letter-spacing:.12em;color:#F5F1E9;margin-bottom:6px}
.opening--camera .season .view{display:flex;align-items:center;justify-content:flex-end;gap:.45em;min-height:44px;margin-top:4px;
  font-size:16px;font-weight:600;line-height:24px;letter-spacing:.02em;text-transform:none;color:#fff;
  text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:5px;
  opacity:0;transform:translateY(4px);transition:opacity .5s ease .15s,transform .6s cubic-bezier(.2,.8,.2,1) .15s}
.opening--camera .season.is-inviting .view,.opening--camera .season:hover .view,
.opening--camera .season:focus-visible .view{opacity:1;transform:none}
/* closest-side, so the shade reaches nothing at every edge of its box: the first version ended in a
   visible straight line above ENTER (seen on a retina render) */
.opening--camera .season::before{content:"";position:absolute;inset:-44px -56px -40px -110px;z-index:-1;pointer-events:none;
  background:radial-gradient(closest-side,rgba(0,0,0,.55),rgba(0,0,0,.32) 55%,rgba(0,0,0,0))}
@media (max-width:760px), (max-aspect-ratio:6/5), (orientation:landscape) and (max-height:540px){
  .opening--camera .season .view{justify-content:flex-start}
  .opening--camera .season::before{display:none}
  /* (Codex review) the ring's compact rule, .opening.opening--carousel .season, is more specific and set
     the season to 10 px on phones; this matches it and, coming later, wins */
  .opening.opening--camera .season{font-size:12px;line-height:18px;letter-spacing:.14em}
}
/* Codex's one-time hint: once per browser, 0.6 s after arrival, gone after 8 s or the first real scroll */
.opening--camera .hint{position:absolute;left:50%;bottom:32px;z-index:8;margin:0;padding:8px 12px;max-width:none;
  background:rgba(0,0,0,.6);color:#F5F1E9;font-size:12px;font-weight:500;line-height:18px;letter-spacing:.03em;
  white-space:nowrap;pointer-events:none;opacity:0;transform:translate(-50%,6px);transition:opacity .2s ease,transform .2s ease}
.opening--camera .hint.is-shown{opacity:1;transform:translate(-50%,0)}
.opening--camera .hint .hint-touch{display:none}
@media (hover:none), (pointer:coarse){
  .opening--camera .hint .hint-mouse{display:none}
  .opening--camera .hint .hint-touch{display:inline}
}
/* [SALMAN] 2026-09-27, the package: the rainbow hangs on the back wall, the only colour there, and is a link
   like the stoles. The plate already holds it; this box is its hit area and a sharper copy of the same
   pixels, which the light raises when the pointer finds it and when the camera turns to it. */
.opening--camera .wall{position:absolute;display:block;cursor:pointer;-webkit-tap-highlight-color:transparent}
.opening--camera .wall img{display:block;width:100%;height:100%;opacity:0;pointer-events:none;
  transition:opacity .6s cubic-bezier(.4,0,.2,1),filter 1.2s cubic-bezier(.4,0,.2,1)}
.opening--camera .wall.is-lit img{opacity:1;filter:brightness(1.22)}
.opening--camera .wall.is-focus img{opacity:1;filter:brightness(1.42)}
.opening--camera .wall:focus{outline:none}
.opening--camera .wall:focus-visible{outline:1px solid rgba(255,255,255,.55);outline-offset:4px}
/* the move into the stole ends in black, then its listing opens */
.opening--camera::after{content:"";position:absolute;inset:0;background:#050505;opacity:0;pointer-events:none;
  z-index:30;transition:opacity .42s cubic-bezier(.5,0,.75,0)}
.opening--camera.is-diving::after{opacity:1}
/* the arrival light over the thread, SOFTENED (Codex, 2026-09-26: "one broad, low-contrast arrival pass
   preserves the thread response he liked without a travelling sparkle"): a wider, gentler band, once */
.opening--camera .fig .glint{filter:brightness(1.3) saturate(1.1);
  -webkit-mask-image:linear-gradient(104deg,transparent 30%,rgba(0,0,0,.7) 50%,transparent 70%);
          mask-image:linear-gradient(104deg,transparent 30%,rgba(0,0,0,.7) 50%,transparent 70%);
  -webkit-mask-size:260% 100%;mask-size:260% 100%}
.opening--camera .fig.is-arriving .glint{animation:fog-glint-soft 1.7s cubic-bezier(.45,.05,.55,.95) both}
@keyframes fog-glint-soft{0%{opacity:0;-webkit-mask-position:85% 0;mask-position:85% 0}
  30%{opacity:.6}70%{opacity:.6}100%{opacity:0;-webkit-mask-position:15% 0;mask-position:15% 0}}
.opening--camera .stagebox,.opening--reveal .stagebox{cursor:default}
/* B: the chosen stole stays in its own light above the darkening room */
.opening--reveal .fig.is-chosen{z-index:10 !important}
.opening--reveal.is-revealing .hit{cursor:progress}

/* arriving on a listing from the opening: the chosen stole's entry is where the eye lands */
/* the sticky header is 50 to 71 px tall on wider screens and wraps to 116 px on narrow phones (measured
   2026-09-26), where the first rule left the entry's season line and photo under it */
.entry{scroll-margin-top:clamp(100px,10vh,120px)}
@media (max-width:413px){.entry{scroll-margin-top:136px}}
.entry:target .plate{outline:1px solid var(--metal);outline-offset:6px;animation:fog-arrive 1.6s cubic-bezier(.2,.8,.2,1) both}
@keyframes fog-arrive{0%{outline-color:transparent}30%{outline-color:var(--metal)}100%{outline-color:var(--metal)}}

/* ---------------------------------------------------------------- opening, the dissolve (D1)
   [SALMAN] 2026-09-25 approved: r9 exactly, only the stole changes. The layers inherit every
   .room rule, so they sit in the base photograph's box at every width and cannot misregister
   (check.py SAME_BOX proves it at every run).
   ⛔ NOT A FLAT CROSSFADE, and the render is why: opacity averages the two colours, so red to
   green passed through a muddy brown and ivory to red through a salmon pink, with both sets of
   embroidery ghosting, for a second each time. That is a stole we do not sell, in the middle of
   the opening. Instead each colour is revealed down the stole behind a soft edge (a mask 3x the
   picture's height: opaque 0-47%, soft 47-53%, clear after, so the soft band is about 18% of the
   picture's height), so only a narrow travelling band is ever mixed and the stole is never one
   averaged colour. The band was 30% until Codex's art note (2026-09-25); rendered side by side,
   18% keeps the mixed embroidery zone visibly tighter and still reads soft.
   Stacking, top last: green, purple, ivory, then red again (the same file as the base) so the
   return to red flows down like the others. Cycle 36 s = four blocks of 6 s hold + 3 s reveal.
   Each layer hides only once the layer above has fully covered it. ⛔ The LOOP POINT too (Codex
   review 2026-09-25): ivory and the top red once reset in the same 3.6 ms, so ivory could show
   through a half-reset red. Now red is fully in by 99.4%, ivory hides beneath it at 99.6%, and
   red resets at 100% over the identical red base, so no two layers ever change together.
   No motion without `.is-ready` (all layers loaded) or under prefers-reduced-motion: the layers
   rest hidden and the page shows the approved red photograph. Without mask support the top red
   layer covers everything, which is the same approved photograph. */
.opening--dissolve .room--layer{opacity:0}
.opening--dissolve.is-ready .room--layer{
  opacity:1;
  -webkit-mask-image:linear-gradient(#000 47%,transparent 53%);mask-image:linear-gradient(#000 47%,transparent 53%);
  -webkit-mask-size:100% 300%;mask-size:100% 300%;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:0 100%;mask-position:0 100%;
  animation:36s ease-in-out infinite both;
}
.opening--dissolve.is-ready .room--green{animation-name:fog-green}
.opening--dissolve.is-ready .room--purple{animation-name:fog-purple}
.opening--dissolve.is-ready .room--ivory{animation-name:fog-ivory}
.opening--dissolve.is-ready .room--red{animation-name:fog-red}
@keyframes fog-green{0%,16.667%{-webkit-mask-position:0 100%;mask-position:0 100%}25%,55%{-webkit-mask-position:0 0;mask-position:0 0}55.01%,100%{-webkit-mask-position:0 100%;mask-position:0 100%}}
@keyframes fog-purple{0%,41.667%{-webkit-mask-position:0 100%;mask-position:0 100%}50%,80%{-webkit-mask-position:0 0;mask-position:0 0}80.01%,100%{-webkit-mask-position:0 100%;mask-position:0 100%}}
@keyframes fog-ivory{0%,66.667%{-webkit-mask-position:0 100%;mask-position:0 100%}75%,99.6%{-webkit-mask-position:0 0;mask-position:0 0}99.61%,100%{-webkit-mask-position:0 100%;mask-position:0 100%}}
@keyframes fog-red{0%,91.667%{-webkit-mask-position:0 100%;mask-position:0 100%}99.4%,99.99%{-webkit-mask-position:0 0;mask-position:0 0}100%{-webkit-mask-position:0 100%;mask-position:0 100%}}

/* ---------------------------------------------------------------- structure */
main{display:block}
.sheet{padding:clamp(48px,6vw,104px) var(--edge)}
.sheet--ink{background:var(--ink);color:var(--paper)}
.sheet--ink a{color:var(--paper)}
.wrap{max-width:1180px;margin:0 auto}
.wrap--narrow{max-width:760px}

h1,h2,h3{font-weight:500;margin:0;line-height:1.12;letter-spacing:-0.01em}
h1{font-size:clamp(30px,4.4vw,58px)}
h2{font-size:clamp(23px,2.7vw,36px)}
h3{font-size:clamp(17px,1.35vw,21px);letter-spacing:0}
p{margin:0 0 1.05em;max-width:var(--measure)}
.lede{font-size:clamp(17px,1.35vw,21px);line-height:1.5;max-width:56ch}

/* the page's own title block: a rule, a title, and the fact. No eyebrow, no pun. */
.head{border-top:1px solid var(--rule-light);padding-top:clamp(18px,2vw,28px);margin-bottom:clamp(28px,3.4vw,52px)}
.sheet--ink .head{border-top-color:var(--rule-dark)}
.head .of{margin:0 0 clamp(14px,1.6vw,22px);font-size:clamp(10px,0.76vw,12px);letter-spacing:.2em;text-transform:uppercase;color:var(--grey)}
.sheet--ink .head .of{color:var(--metal)}

/* ---------------------------------------------------------------- the register */
.register{border-top:1px solid var(--rule-light);margin-top:clamp(30px,3.6vw,54px)}
.sheet--ink .register{border-top-color:var(--rule-dark)}
.entry{
  display:grid;
  grid-template-columns:minmax(0,248px) minmax(0,1fr) minmax(0,26ch);
  gap:var(--gap);
  align-items:start;
  padding:clamp(22px,2.6vw,36px) 0;
  border-bottom:1px solid var(--rule-light);
}
.sheet--ink .entry{border-bottom-color:var(--rule-dark)}
.entry .plate{background:var(--black);border:1px solid var(--rule-light);aspect-ratio:4/5;overflow:hidden}
.sheet--ink .entry .plate{background:var(--black);border-color:var(--rule-dark)}
.entry .plate img{width:100%;height:100%;object-fit:contain}
.entry h3{margin-bottom:.4em}
.entry p{margin-bottom:.55em}
.entry .season{font-size:clamp(10px,0.76vw,12px);letter-spacing:.18em;text-transform:uppercase;color:var(--grey)}
.sheet--ink .entry .season{color:var(--metal)}
.spec{margin:0;font-size:clamp(13px,0.9vw,14.5px);line-height:1.55;color:var(--grey)}
.sheet--ink .spec{color:var(--metal)}
.spec div{display:flex;justify-content:space-between;gap:1.2em;border-bottom:1px solid var(--rule-light);padding:.32em 0}
.sheet--ink .spec div{border-bottom-color:var(--rule-dark)}
.spec div:last-child{border-bottom:0}
.spec dt,.spec dd{margin:0}
.spec dt{white-space:nowrap}
.spec dd{hyphens:none}
.spec dd{text-align:right;color:var(--ink)}
.sheet--ink .spec dd{color:var(--paper)}

/* ---------------------------------------------------------------- tables */
.table{width:100%;border-collapse:collapse;margin:0 0 1.6em;font-size:clamp(14px,0.96vw,15.5px)}
.table caption{text-align:left;padding-bottom:.8em;color:var(--grey);font-size:clamp(12px,0.84vw,13.5px)}
.table th,.table td{text-align:left;vertical-align:top;padding:.62em .9em .62em 0;border-bottom:1px solid var(--rule-light)}
.table th{font-weight:500;white-space:nowrap;width:12.5em}
.table tr:last-child th,.table tr:last-child td{border-bottom:0}
.tablewrap{overflow-x:auto}

.source{font-size:clamp(12px,0.82vw,13px);color:var(--grey);max-width:var(--measure)}
.source a{color:inherit}

/* ---------------------------------------------------------------- links */
.next{
  display:inline-flex;align-items:center;gap:12px;text-decoration:none;
  font-size:clamp(11px,0.8vw,13px);letter-spacing:.2em;text-transform:uppercase;
  border-bottom:1px solid currentColor;padding-bottom:3px;
}
.next .rule{display:block;width:clamp(20px,2.4vw,34px);height:1px;background:currentColor;transition:width .38s cubic-bezier(.2,.7,.2,1)}
.next:hover .rule{width:clamp(34px,4vw,54px)}

.cols{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));gap:var(--gap)}

/* ---------------------------------------------------------------- enquiry */
.field{display:block;margin:0 0 clamp(16px,1.8vw,24px);max-width:var(--measure)}
.field span{display:block;font-size:clamp(11px,0.8vw,12.5px);letter-spacing:.16em;text-transform:uppercase;color:var(--grey);margin-bottom:.55em}
.field input,.field select,.field textarea{
  width:100%;font:inherit;color:inherit;background:var(--white);
  border:1px solid var(--rule-light);border-radius:0;padding:.72em .85em;
}
.field textarea{min-height:8.5em;resize:vertical}
button.send{
  font:inherit;letter-spacing:.2em;text-transform:uppercase;font-size:clamp(11px,0.8vw,13px);
  background:var(--ink);color:var(--paper);border:1px solid var(--ink);
  padding:.95em 2.2em;cursor:pointer;
}
button.send:hover{background:var(--black)}

/* ---------------------------------------------------------------- a stole's own page
   [SALMAN] 2026-09-26 (DECISIONS 09-26j): where a click on a stole lands. A large photograph, the
   season and the words, one clear action ("Enquire about this stole"), the embroidery and the fringe
   close, and the other stoles. The stoles page's entries lead here too. */
.entry a.plate{display:block}
.entry h3 a{color:inherit;text-decoration:none}
.stole-page .back{margin:0 0 clamp(22px,2.6vw,40px)}
.stole-hero{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);gap:clamp(28px,4.5vw,88px);align-items:start}
.stole-hero__plate{margin:0;background:var(--black);border:1px solid var(--rule-dark)}
.stole-hero__plate img{display:block;width:100%;height:auto}
.stole-hero__text .of{margin:0 0 .9em;font-size:clamp(10px,0.76vw,12px);letter-spacing:.2em;text-transform:uppercase;color:var(--metal)}
.stole-hero__text h1{margin:0 0 .45em}
.stole-hero__text .spec{margin-top:clamp(24px,2.6vw,38px)}
.stole-cta{margin:clamp(24px,2.6vw,36px) 0 .9em}
a.enquire,.sheet--ink a.enquire{display:inline-block;text-decoration:none;font-size:clamp(12px,0.86vw,14px);letter-spacing:.2em;
  text-transform:uppercase;background:var(--paper);color:var(--ink);border:1px solid var(--paper);padding:1.05em 2.3em;
  transition:background .3s ease,color .3s ease}
a.enquire:hover,.sheet--ink a.enquire:hover{background:transparent;color:var(--paper)}
.stole-how{color:var(--metal);font-size:clamp(13px,0.9vw,14.5px);line-height:1.55;max-width:46ch}
.stole-close{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(14px,2vw,28px)}
.stole-close figure{margin:0;background:var(--black);border:1px solid var(--rule-dark)}
.stole-close img{display:block;width:100%;height:auto}
.stole-closer .stole-cta{text-align:center;margin-top:clamp(30px,3.2vw,48px);max-width:none}
.others{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:clamp(12px,1.6vw,24px)}
.other{display:block;text-decoration:none;color:inherit}
.other img{display:block;width:100%;aspect-ratio:4/5;object-fit:contain;background:var(--black);border:1px solid var(--rule-light)}
.other span{display:block;margin-top:.8em;font-size:clamp(15px,1.1vw,18px)}
.other small{display:block;margin-top:.3em;color:var(--grey);font-size:clamp(10px,0.74vw,11.5px);letter-spacing:.16em;text-transform:uppercase}
@media (max-width:760px){
  .stole-hero{grid-template-columns:1fr}
  .stole-close{grid-template-columns:1fr}
  a.enquire,.sheet--ink a.enquire{display:block;text-align:center}
}
/* five in a two-column grid leaves one alone; on a phone they are a list instead, a small picture beside
   each name and its days */
@media (max-width:760px){
  .others{grid-template-columns:1fr;gap:12px}
  .other{display:grid;grid-template-columns:64px minmax(0,1fr);grid-template-rows:auto auto;column-gap:16px;align-content:center}
  .other img{grid-row:1 / 3}
  .other span{margin-top:0;align-self:end}
  .other small{align-self:start}
}

/* ---------------------------------------------------------------- who runs Fogrio (DECISIONS 09-27a) */
.foot .legal{margin-top:1em;font-size:clamp(11px,0.78vw,12.5px);line-height:1.55;color:var(--grey)}
.consent{font-size:clamp(12px,0.84vw,13.5px);color:var(--grey);margin:clamp(6px,1vw,12px) 0 clamp(16px,1.8vw,24px)}
.or{margin-top:clamp(20px,2.2vw,30px);color:var(--grey)}
.or a{color:inherit}
.hp{display:none}
.privacy h3{margin:clamp(22px,2.4vw,32px) 0 .45em}

/* ---------------------------------------------------------------- the two chapters (DECISIONS 09-27e)
   [SALMAN] 2026-09-27, the package: "The church year" and "For inclusive worship", in the same atelier
   photography, on the same dark sheet, with pictures of the same size, so neither reads as the other's
   annex. */
.chapter__plate{margin:clamp(26px,3.2vw,46px) 0 0;border:1px solid var(--rule-dark);background:#050505}
.chapter__plate a,.chapter__plate picture{display:block}
.chapter__plate img{display:block;width:100%;height:auto}
.chapter__lede{margin-top:clamp(24px,2.8vw,40px)}
.chapter .others{margin-top:clamp(22px,2.6vw,38px)}
.chapter__more{margin-top:clamp(26px,2.8vw,40px)}
.chapter h2 a{color:inherit;text-decoration:none}
.chapter__text{display:grid;grid-template-columns:minmax(0,1.4fr) minmax(0,1fr);gap:clamp(24px,5vw,96px);
  align-items:end;margin-top:clamp(24px,2.8vw,40px)}
.chapter__text .lede{margin:0}
.chapter__text .stole-cta{margin-top:0}
@media (max-width:760px){.chapter__text{grid-template-columns:1fr}}
.sheet--ink .other img{border-color:var(--rule-dark)}
.sheet--ink .other small{color:var(--metal)}
.jump{margin:clamp(18px,2vw,26px) 0 0}
/* a jump (ENTER, the stoles page's shortcut) stops just below the sticky header, whose height was measured
   at 50 to 71 px on wide screens, 81 px at 414 wide, and 116 px when it wraps on narrow phones */
#house,#inclusive-worship,#rainbow-stole,#church-year,#stained-glass,#shop,[id^="shop-"]{scroll-margin-top:72px}
@media (max-width:760px){#house,#inclusive-worship,#rainbow-stole,#church-year,#stained-glass,#shop,[id^="shop-"]{scroll-margin-top:84px}}
@media (max-width:413px){#house,#inclusive-worship,#rainbow-stole,#church-year,#stained-glass,#shop,[id^="shop-"]{scroll-margin-top:118px}}
/* 2026-10-22: the store's sections clear the sticky header too (check_directions found every shop anchor landing at
   y 0, under a 50 to 116 px header, on all 14 widths) */
.stole-note{margin-top:clamp(20px,2.2vw,30px);font-size:clamp(13px,0.9vw,14.5px);line-height:1.55;color:var(--metal);max-width:52ch}

/* ---------------------------------------------------------------- footer */
.foot{
  background:var(--black);color:var(--metal);
  padding:clamp(40px,4.6vw,72px) var(--edge);
  border-top:1px solid var(--rule-dark);
  font-size:clamp(12px,0.84vw,13.5px);
}
.foot .wrap{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(220px,100%),1fr));gap:var(--gap)}
.foot h3{font-size:clamp(11px,0.8vw,12.5px);letter-spacing:.2em;text-transform:uppercase;color:var(--paper);margin-bottom:.9em}
.foot ul{list-style:none;margin:0;padding:0}
.foot li{margin-bottom:.42em}
.foot a{text-decoration:none;border-bottom:1px solid transparent}
.foot a:hover{border-bottom-color:currentColor}
.foot .wm{width:132px;color:var(--paper);margin-bottom:1.1em}
.foot .wm svg{display:block;width:100%;height:auto}

/* ---------------------------------------------------------------- narrow */
@media (max-width:860px){
  .entry{grid-template-columns:minmax(0,168px) minmax(0,1fr);}
  .entry .spec{grid-column:1 / -1}
}
/* narrow phones (Codex, 2026-09-27): the description ran in a column about three words wide beside the
   photograph. Now the photograph sits beside the season and the name, and the words and the measurements
   run the full width beneath. */
@media (max-width:560px){
  .entry{grid-template-columns:minmax(0,40%) minmax(0,1fr);row-gap:.8em}
  .entry > div:not(.plate){display:contents}
  .entry .plate{grid-column:1;grid-row:1 / span 2}
  .entry .season{grid-column:2;grid-row:1;align-self:end;margin:0}
  .entry h3{grid-column:2;grid-row:2;align-self:start}
  .entry > div:not(.plate) > p:not(.season){grid-column:1 / -1}
  .entry .spec{grid-column:1 / -1}
}
@media (max-width:760px){
  /* ⛔ THE DEFECT THIS SHAPE FIXES, found by looking at the render and by nothing else:
     the room sits FIRST in the markup, so `grid-template-rows:auto 1fr` gave the image the
     `auto` row. Its only child is absolutely positioned, so its intrinsic height is ZERO and
     the entire opening screen rendered as a black rectangle with no vestment in it. The probe
     still reported a true viewport and no overflow, because neither of those is a picture.
     `order:-1` puts the mark in the auto row and gives the room the 1fr row it needs. */
  .opening{display:grid;grid-template-rows:auto minmax(0,1fr)}
  .opening .plate-head{order:-1;position:relative;z-index:3;background:var(--black);padding:clamp(44px,7vh,68px) var(--edge) clamp(20px,3vh,30px)}
  .opening .mark{position:static;width:min(430px,86vw)}
  .opening .place{position:static;margin-top:clamp(12px,2vh,18px);font-size:11px;letter-spacing:.2em}
  .opening .roomwrap{position:relative;overflow:hidden;min-height:0}
  .opening .room{position:absolute;inset:0;object-position:50% 40%}
  .opening .enter{left:var(--edge);bottom:clamp(20px,3vh,32px);font-size:11px}
  .masthead{flex-wrap:wrap;gap:12px}
  .masthead nav{width:100%;justify-content:flex-start;gap:16px}
  .masthead nav a{font-size:10px;letter-spacing:.14em}
}
@media (min-width:761px){
  .opening .plate-head{display:contents}
  .opening .roomwrap{position:absolute;inset:0}
}

@media (prefers-reduced-motion:reduce){
  *{transition:none !important;animation:none !important;scroll-behavior:auto !important}
}

/* ---------------------------------------------------------------- the stained glass collection (DECISIONS 09-28f)
   Six printed stoles led by the rainbow: two rows of three (Codex's placement), the others row on a stole page
   keeps to its own collection and leads on to the other one. */
.others.others--glass{grid-template-columns:repeat(3,minmax(0,1fr))}
/* ⛔ on a phone the six are a list like the five: three columns of card text widened the whole phone page to
   431 px (measured 2026-09-28, the first build of this chapter) */
@media (max-width:760px){.others.others--glass{grid-template-columns:1fr}}
.others-more{margin-top:clamp(22px,2.4vw,34px)}
.jump .next + .next{margin-left:clamp(22px,3vw,44px)}
@media (max-width:560px){.jump .next{display:inline-flex;margin:0 0 10px}.jump .next + .next{margin-left:0}.jump{display:flex;flex-direction:column;align-items:flex-start}}
/* the camera home: a quiet second way in, beside ENTER, to the stained glass (Codex's placement). ENTER keeps
   its own look; the door is the same small capitals, one step quieter. */
.opening--camera .doors{margin:0;z-index:7;display:flex;align-items:center;gap:clamp(22px,2.6vw,36px)}
.opening--camera .doors .enter{position:static}
.opening--camera .door{color:var(--metal);text-decoration:none;font-size:clamp(10px,0.74vw,12px);letter-spacing:.22em;
  text-transform:uppercase;display:inline-flex;align-items:center;min-height:24px}
.opening--camera .door:hover,.opening--camera .door:focus-visible{color:var(--paper)}
@media (min-width:761px) and (min-aspect-ratio:6/5){
  .opening--camera .doors{position:absolute;right:var(--edge);bottom:clamp(34px,4.8vh,54px);flex-direction:row-reverse}
}
@media (max-width:760px), (max-aspect-ratio:6/5){
  .opening.opening--camera .doors{position:static;flex:0 0 auto;margin:14px var(--edge) clamp(14px,3svh,26px);justify-content:space-between}
  .opening.opening--camera .doors .enter{margin:0}
}
@media (orientation:landscape) and (max-height:540px){
  .opening.opening--camera .doors{position:static;grid-column:1;grid-row:3;margin:14px var(--edge) 18px;flex-direction:column;align-items:flex-start;gap:10px}
  .opening.opening--camera .doors .enter{margin:0}
}

/* ---------------------------------------------------------------- CALM, 2026-10-22
   [SALMAN] "i like how it is but i'd want it to be more stable, smooth, relaxing, easy on eyes". Converged with
   Astra and Sol 6.1 (.tmp/fogrio_round_2026-10-22/CONVERGED_PLAN.md A). The page he likes, with the effects
   that changed several things at once taken out: no blur on the stoles the camera leaves, no shimmer on arrival,
   no floor-light swell. Type for reading, not decoration: 13 to 15 px, far less letter-spacing. */
.opening--camera .fig.is-away{filter:none}
.opening--camera .fig.is-arriving .glint{animation:none;opacity:0}
.opening--camera .pool.is-swelling{animation:none}
.opening--camera .place{font-size:13px;letter-spacing:.12em}
.opening--camera .enter,.opening--camera .door,.opening--camera .tour,.opening--camera .overview{
  font-size:14px;letter-spacing:.08em;min-height:44px}
.opening--camera .tour,.opening--camera .overview{appearance:none;background:none;border:0;padding:0;margin:0;
  font-family:inherit;text-transform:uppercase;color:var(--metal);cursor:pointer;display:inline-flex;align-items:center}
.opening--camera .tour:hover,.opening--camera .tour:focus-visible,.opening--camera .overview:hover,
.opening--camera .overview:focus-visible,.opening--camera .tour[aria-pressed="true"]{color:var(--paper)}
.opening--camera .overview[hidden],.opening--camera .tour[hidden]{display:none}
.opening--camera .season{font-size:14px;letter-spacing:.08em}
.opening--camera .season b{font-size:17px;letter-spacing:.06em}
.opening--camera .hint{font-size:14px}
.opening--camera .calm{position:absolute;top:clamp(18px,3vh,30px);right:var(--edge);z-index:8;margin:0;
  display:flex;align-items:center;gap:26px}

/* ---------------------------------------------------------------- THE STORE, 2026-10-22
   [SALMAN] "the site will be ecommerce store with prices and free delivery". The same language as the rest of the
   house: ink sheets, paper type, the paper button; prices plain and large enough to read without hunting. */
.opening--camera[hidden]{display:none!important}
/* (2026-10-27: the whole-room opacity fade that let the paper-white page flash through is gone; see the passing shadow) */
.opening--camera .tabs{position:absolute;top:clamp(18px,3vh,30px);left:var(--edge);z-index:8;display:flex;gap:6px;margin:0}
.opening--camera .tabs .tab{color:var(--metal);text-decoration:none;font-size:14px;letter-spacing:.06em;padding:.55em .9em;
  border:1px solid transparent;min-height:44px;display:inline-flex;align-items:center}
.opening--camera .tabs .tab:hover,.opening--camera .tabs .tab:focus-visible{color:var(--paper)}
.opening--camera .tabs .tab[aria-current="true"]{color:var(--paper);border-color:rgba(244,243,241,.45)}
/* 2026-10-22: zoomed in on the stained glass, "Play tour" sat on the Tree figure's WHITE collar and "Play" vanished. Both
   control rows carry a quiet dark backing of their own, so they read over any part of the room at any zoom (the keep-clear
   framing measures these boxes, so the backing is kept clear too) */
.opening--camera .calm{background:rgba(11,11,12,.6);padding:2px 14px}
.opening--camera .tabs{background:rgba(11,11,12,.6);padding:3px}
@media (max-width:760px), (max-aspect-ratio:6/5){
  .opening--camera .tabs{background:none;padding:0}
  .opening--camera .tabs{position:static;margin:12px var(--edge) 0;flex-wrap:wrap;gap:4px}
  .opening--camera .tabs .tab{font-size:13px;padding:.5em .7em}
}
.house .lede{max-width:60ch}
.shop .coll{margin-bottom:clamp(48px,6vw,88px)}
.coll-head{display:flex;justify-content:space-between;align-items:baseline;gap:1em;flex-wrap:wrap;border-top:1px solid var(--rule-dark);
  padding-top:clamp(16px,1.8vw,24px);margin-bottom:clamp(20px,2.4vw,34px)}
.coll-head h2,.coll-head h1{margin:0}
.coll-head p{margin:0;color:var(--metal);font-size:clamp(13px,.95vw,15px)}
.cards{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:clamp(14px,1.8vw,28px)}
/* 2026-10-22: one full row per collection on a desktop (the six stained glass stoles left Spirit and Flame alone on a
   second row of a five-column grid); three a row on a tablet; two on a phone, where one a row made the home 12,500 px */
.cards--4{grid-template-columns:repeat(4,minmax(0,1fr))}
.cards--6{grid-template-columns:repeat(6,minmax(0,1fr))}
@media (max-width:999px){.cards,.cards--4,.cards--6{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:599px){.cards,.cards--4,.cards--6{grid-template-columns:repeat(2,minmax(0,1fr));gap:18px 12px}}
.card{display:block;text-decoration:none;color:inherit}
.sheet--ink a.card{color:var(--paper)}
.card img{display:block;width:100%;height:auto;aspect-ratio:2/3;object-fit:cover;background:#3b3b3b}
.card-name{display:block;margin-top:.8em;font-size:clamp(15px,1.05vw,17px)}
.card-price{display:block;margin-top:.25em;font-size:clamp(15px,1.05vw,17px);color:var(--paper)}
.card-note{display:block;margin-top:.3em;color:var(--metal);font-size:12px;letter-spacing:.12em;text-transform:uppercase}
.card:hover .card-name{text-decoration:underline;text-underline-offset:4px}
.product .gallery .main{margin:0;background:#3b3b3b;border:1px solid var(--rule-dark);aspect-ratio:2/3;overflow:hidden}
.product .gallery .main img{display:block;width:100%;height:100%;object-fit:cover}
.product .thumbs{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:8px;margin-top:10px}
.product .thumb{appearance:none;padding:0;border:1px solid var(--rule-dark);background:#2a2a2a;cursor:pointer;aspect-ratio:2/3;overflow:hidden}
.product .thumb img{display:block;width:100%;height:100%;object-fit:cover}
.product .thumb[aria-current="true"]{border-color:var(--paper)}
.product .price{font-size:clamp(24px,2vw,30px);margin:.2em 0 .1em;color:var(--paper)}
.product .free{color:var(--metal);margin:0 0 1.2em}
.buy{display:flex;gap:12px;align-items:end;flex-wrap:wrap;margin:0 0 .8em}
.qty{display:flex;flex-direction:column;gap:6px;font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--metal)}
.qty input{width:84px;min-height:48px;font:inherit;font-size:16px;letter-spacing:0;text-transform:none;padding:0 .7em;
  background:transparent;color:var(--paper);border:1px solid var(--rule-dark)}
button.add{appearance:none;cursor:pointer;font:inherit;font-size:clamp(12px,.86vw,14px);letter-spacing:.2em;text-transform:uppercase;
  background:var(--paper);color:var(--ink);border:1px solid var(--paper);padding:0 2.3em;min-height:48px;transition:background .3s ease,color .3s ease}
button.add:hover,button.add:focus-visible{background:transparent;color:var(--paper)}
.added{color:var(--paper);margin:.2em 0 1em}
.added a{color:var(--paper)}
.stitched{border-left:2px solid var(--metal);padding-left:.9em;color:var(--paper);margin:1.2em 0}
.product .small,.small{color:var(--metal);font-size:13px}
.small a{color:inherit}
.cart .line{display:grid;grid-template-columns:90px minmax(0,1fr) auto auto auto;gap:14px;align-items:center;padding:14px 0;border-bottom:1px solid var(--rule-dark)}
.cart .line img{display:block;width:90px;height:auto;background:#3b3b3b}
.cart .line-text a{display:block;color:var(--paper);text-decoration:none;font-size:16px}
.cart .line-text span{display:block;color:var(--metal);font-size:13px;margin-top:.3em}
.cart .line-total{color:var(--paper);min-width:5.5em;text-align:right}
.cart .remove{appearance:none;background:none;border:0;color:var(--metal);cursor:pointer;font:inherit;font-size:13px;text-decoration:underline;padding:8px 0;min-height:44px}
.cart .totals{margin-top:18px;max-width:340px;margin-left:auto}
.cart .totals div{display:flex;justify-content:space-between;padding:.45em 0;color:var(--metal)}
.cart .totals .grand{color:var(--paper);font-size:18px;border-top:1px solid var(--rule-dark);margin-top:.3em;padding-top:.7em}
.cart .go{text-align:right;margin-top:22px}
.cart-empty a{color:var(--paper)}
@media (max-width:620px){
  .cart .line{grid-template-columns:70px minmax(0,1fr) auto;grid-template-areas:"img text total" "img qty remove"}
  .cart .line img{grid-area:img;width:70px}
  .cart .line-text{grid-area:text}.cart .line .qty{grid-area:qty}.cart .line-total{grid-area:total}.cart .remove{grid-area:remove;justify-self:end}
}
.pay{min-height:420px;margin:18px 0}
.pay-wait,.pay-error{color:var(--metal)}
.pay-error a{color:var(--paper)}
.policy-page p{max-width:62ch}

/* ---------------------------------------------------------------- THE HOMEPAGE BELOW THE ROOMS, 2026-10-22
   [SALMAN] "the listings on the homepage, they look as if they are midgets and congested ... not as creative as the
   grand opening". Converged with Astra and Sol: every stole stays here, in an editorial chapter per collection, on a
   shelf of large pictures that runs off the edge of the screen. The shelf never takes the page's vertical scroll. */
.chapter{border-top:1px solid var(--rule-dark)}
.chapter-head{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);gap:var(--gap);align-items:end}
.chapter-head h2{font-size:clamp(34px,4.3vw,66px);line-height:1.04;margin:.25em 0 0;max-width:14ch}
.chapter-head .lede{margin:0 0 .9em}
.chapter-price{color:var(--metal);font-size:14px;letter-spacing:.1em;text-transform:uppercase;margin:0 0 .9em}
.chapter-names{display:flex;flex-wrap:wrap;gap:6px 18px;margin:0}
.chapter-names a{color:var(--paper);font-size:15px;text-decoration:underline;text-decoration-color:var(--rule-dark);text-underline-offset:5px}
.chapter-names a:hover{text-decoration-color:var(--paper)}
.shelf-row{margin-top:clamp(36px,4vw,60px)}
.shelf{display:flex;gap:clamp(16px,2vw,30px);overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;
  scrollbar-width:none;margin-right:calc(-1 * var(--edge));padding:4px var(--edge) 6px max(0px,calc((100% - 1180px) / 2));
  scroll-padding-left:max(0px,calc((100% - 1180px) / 2))}
.shelf::-webkit-scrollbar{display:none}
.shelf .card{flex:0 0 clamp(270px,27vw,420px);scroll-snap-align:start}
.card-pics{position:relative;display:block;aspect-ratio:2/3;overflow:hidden;background:#3b3b3b}
.card .card-pics img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:opacity .5s ease,transform .9s ease}
.card .card-pics .card-alt{opacity:0}
@media (hover:hover){
  .card:hover .card-pics .card-alt,.card:focus-visible .card-pics .card-alt{opacity:1}
  .card:hover .card-pics img:first-child{transform:scale(1.015)}
}
.card.is-called .card-pics{outline:1px solid var(--paper);outline-offset:5px}
.shelf-nav{display:flex;align-items:center;justify-content:flex-end;gap:12px;margin-top:22px}
.shelf-pos{margin-right:auto;color:var(--metal);font-size:13px;letter-spacing:.12em;text-transform:uppercase}
.shelf-nav button{width:46px;height:46px;border:1px solid var(--rule-dark);border-radius:50%;background:transparent;color:var(--paper);
  font-size:18px;cursor:pointer;transition:border-color .3s}
.shelf-nav button:hover:not(:disabled){border-color:var(--paper)}
.shelf-nav button:disabled{opacity:.3;cursor:default}
.is-all-in-view .shelf-nav button{display:none}
/* which stole for which day */
.occasions{margin-top:clamp(36px,4vw,56px)}
.occasion-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));gap:12px}
.occasion{display:flex;flex-direction:column;gap:5px;padding:16px 18px;border:1px solid var(--rule-dark);color:var(--paper);
  text-decoration:none;transition:border-color .3s}
.occasion span{color:var(--metal);font-size:12px;letter-spacing:.14em;text-transform:uppercase}
.occasion b{font-weight:normal;font-size:18px}
.occasion:hover,.occasion:focus-visible{border-color:var(--paper)}
/* how they are made */
.making-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(14px,1.8vw,28px)}
.making-tile{margin:0}
.making-tile img{display:block;width:100%;height:auto;aspect-ratio:2/3;object-fit:cover;background:#3b3b3b}
.making-tile figcaption{margin-top:.9em;color:var(--metal);font-size:15px;line-height:1.5}
.making-tile figcaption b{display:block;color:var(--paper);font-weight:normal;font-size:18px;margin-bottom:.25em}
/* buy with confidence */
.confidence{list-style:none;padding:0;margin:18px 0;display:grid;gap:7px}
.confidence li{font-size:15px;color:var(--metal);line-height:1.45}
.confidence b{color:var(--paper);font-weight:normal}
/* three promises since 10-27h (returns moved to the Returns page): three columns, so no empty quarter */
.confidence--wide{grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(14px,2vw,32px);margin:0 0 1.6em}
.confidence--wide li{border-top:1px solid var(--rule-dark);padding-top:16px;font-size:16px}
.confidence--wide b{display:block;font-size:19px;margin-bottom:.2em}
/* the stole page */
.product .hook{font-size:clamp(18px,1.35vw,21px);line-height:1.45;color:var(--paper);margin:.3em 0 .9em;max-width:36ch}
.product .twin{border-left:2px solid var(--rule-dark);padding-left:14px;color:var(--metal);font-size:15px}
.product .twin a{color:var(--paper)}
.product h2.minor{font-size:13px;font-weight:normal;letter-spacing:.16em;text-transform:uppercase;color:var(--metal);margin:2.2em 0 .5em}
.cards--wide{grid-template-columns:repeat(3,minmax(0,1fr))}
@media (max-width:999px){
  .chapter-head{grid-template-columns:1fr;gap:12px}
  .making-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .cards--wide{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:599px){
  .shelf .card{flex-basis:74vw}
  .confidence--wide{grid-template-columns:1fr}
  .occasion-list{grid-template-columns:repeat(2,minmax(0,1fr))}
}

.product .stole-note{font-size:inherit;line-height:inherit;color:inherit}   /* "When it is worn" reads like its neighbours */

/* checkout: what the buyer must know BEFORE paying (Google Merchant misrepresentation policy; 2026-10-26) */
.before-pay{list-style:none;margin:0 0 22px;padding:14px 16px;border:1px solid rgba(255,255,255,.14);border-radius:4px;max-width:62ch}
.before-pay li{color:var(--metal);font-size:14px;line-height:1.55;margin:0}
.before-pay li+li{margin-top:8px}
.before-pay a{color:inherit}

/* ================================================================ 2026-10-26 go-live (Claude + Astra + Sol, DECISIONS 10-26n)
   The header sits ABOVE the opening on every page (it used to sit under the rooms on the homepage), at a fixed height, so
   the rooms can be sized to the screen MINUS the header: they size from their own box (container queries), so they
   rescale exactly as on any other screen. On a phone the links fold into a Menu sheet (they were 10px and wrapped). */
:root{--mh:64px}
@media (max-width:860px){:root{--mh:56px}}
.masthead{height:var(--mh);padding-top:0;padding-bottom:0;box-sizing:border-box}
.masthead .wm{width:clamp(104px,9.5vw,140px)}
.masthead .nav-wide{display:flex;align-items:center;gap:clamp(18px,2.2vw,36px);flex-wrap:nowrap}
.masthead .nav-wide a{font-size:12px;letter-spacing:.18em}
.masthead .cartlink{text-decoration:none;font-size:12px;letter-spacing:.18em;text-transform:uppercase;opacity:.84;
  padding-bottom:2px;border-bottom:1px solid transparent;white-space:nowrap}
.masthead .cartlink:hover,.masthead .cartlink[aria-current="page"]{opacity:1;border-bottom-color:currentColor}
.masthead .nav-narrow{display:none}
@media (max-width:860px){
  .masthead .nav-wide{display:none}
  .masthead .nav-narrow{display:flex;align-items:center;gap:20px}
  .masthead .cartlink{font-size:13px;display:inline-flex;align-items:center;min-height:44px}
  .menu summary{list-style:none;cursor:pointer;font-size:13px;letter-spacing:.18em;text-transform:uppercase;
    min-height:44px;display:flex;align-items:center;padding:0 2px;color:var(--paper)}
  .menu summary::-webkit-details-marker{display:none}
  .menu[open] summary{border-bottom:1px solid currentColor}
  .menu .menu-sheet{position:fixed;top:var(--mh);left:0;right:0;bottom:0;z-index:40;background:var(--black);
    display:flex;flex-direction:column;padding:18px var(--edge) 40px;overflow:auto;border-top:1px solid var(--rule-dark)}
  .menu .menu-sheet a{font-size:24px;line-height:1.2;letter-spacing:.02em;text-transform:none;opacity:1;text-decoration:none;
    padding:16px 0;border-bottom:1px solid var(--rule-dark);color:var(--paper)}
  .menu .menu-sheet a[aria-current="page"]{color:var(--metal)}
  .menu .menu-foot{margin-top:auto;padding-top:24px}
  .menu .menu-foot a{font-size:15px;border:0;color:var(--metal)}
}
.masthead .menu-foot{margin:0}

/* the homepage: the header first, then the rooms at the screen's height minus the header */
.opening.opening--carousel.opening--camera{height:calc(100svh - var(--mh));min-height:440px}
@media (max-width:760px), (max-aspect-ratio:6/5){
  .opening.opening--carousel.opening--camera{height:calc(100svh - var(--mh));min-height:0}
  /* the header carries the wordmark on a phone, so the room's own heading is kept for readers but not shown twice */
  .opening.opening--carousel.opening--camera .plate-head{position:absolute;width:1px;height:1px;overflow:hidden;
    clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;padding:0}
}
@media (orientation:landscape) and (max-height:540px){
  .opening.opening--carousel.opening--camera{height:calc(100svh - var(--mh));min-height:0}
}

/* the footer: brand, shop, occasions, help; the legal line under it all */
.foot .wrap{grid-template-columns:minmax(0,1.4fr) repeat(3,minmax(0,1fr))}
.foot .foot-tag{color:var(--paper);font-size:clamp(14px,1vw,16px);margin:0 0 .6em}
.foot .foot-promise{margin:0 0 .6em}
.foot .foot-legal{display:block;margin-top:clamp(28px,3vw,44px);padding-top:18px;border-top:1px solid var(--rule-dark)}
.foot .foot-legal .legal{margin:0}
@media (max-width:860px){.foot .wrap{grid-template-columns:repeat(2,minmax(0,1fr))}.foot .foot-brand{grid-column:1 / -1}}

/* ================================================================ occasions, about, contact (2026-10-26, BUILD_SPEC §§7-9)
   Light sheets for reading (the church-year guide and the occasion pages: Salman found the dark guide "not as pleasant
   as it should be"), ink sheets where the stoles are shown (their photographs were made for a dark ground). */
.minor{font-size:clamp(13px,.9vw,14px);letter-spacing:.18em;text-transform:uppercase;font-weight:500;margin:2.2em 0 .9em;color:var(--grey)}
.sheet--ink .minor{color:var(--metal)}
.small{font-size:clamp(13px,.92vw,14.5px);line-height:1.6;color:var(--grey);max-width:var(--measure)}
.sheet--ink .small{color:var(--metal)}

.occ-hero{padding-top:clamp(32px,4vw,64px)}
.occ-hero__grid{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:clamp(28px,4vw,72px);align-items:start}
.occ-hero__art{margin:0;position:sticky;top:calc(var(--mh) + 24px)}
.occ-hero__art img{width:100%;height:auto;aspect-ratio:3/2;object-fit:cover;box-shadow:0 1px 0 var(--rule-light),0 24px 60px -32px rgba(11,11,12,.45)}
.occ-hero__text .of{margin:0 0 14px;font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--grey)}
.occ-hero__text .of a{text-decoration:none}
.occ-hero__text .of a:hover{text-decoration:underline;text-underline-offset:4px}
.occ-hero__text h1{margin-bottom:.5em}
.days{list-style:none;padding:0;margin:0 0 1.2em;border-top:1px solid var(--rule-light)}
.days li{display:flex;justify-content:space-between;align-items:baseline;gap:1em;padding:.7em 0;border-bottom:1px solid var(--rule-light)}
.days li[hidden]{display:none}
.days b{font-weight:500}
.days span{color:var(--grey);text-align:right;font-size:.95em}
.days .dnote{display:block;font-size:.86em}
.undated{max-width:var(--measure)}
.occ-jump{margin-top:1.6em}
.occ-guide{padding-top:clamp(24px,3vw,48px);border-top:1px solid var(--rule-light)}
.occ-cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(28px,4vw,72px)}
.occ-cols .minor:first-child{margin-top:0}
.trad{margin:0;border-top:1px solid var(--rule-light)}
.trad div{display:grid;grid-template-columns:minmax(0,11em) minmax(0,1fr);gap:1em;padding:.8em 0;border-bottom:1px solid var(--rule-light)}
.trad dt{font-weight:500}
.trad dd{margin:0}
.sheet--ink .trad,.sheet--ink .trad div{border-color:var(--rule-dark)}
.buyinfo{margin-top:clamp(36px,4vw,56px)}
.occ-more{padding-top:clamp(28px,3vw,44px);padding-bottom:clamp(28px,3vw,44px)}
.occ-more__grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.occ-step{display:flex;flex-direction:column;gap:4px;padding:16px 18px;border:1px solid var(--rule-light);text-decoration:none}
.occ-step span{font-size:12px;letter-spacing:.16em;text-transform:uppercase;color:var(--grey)}
.occ-step b{font-weight:500;font-size:clamp(16px,1.15vw,19px)}
.occ-step:hover,.occ-step:focus-visible{border-color:var(--ink)}
.occ-step--all{text-align:center}
.occ-step--next{text-align:right}
@media (max-width:860px){
  .occ-hero__grid,.occ-cols{grid-template-columns:1fr}
  .occ-hero__art{position:static}
  .trad div{grid-template-columns:1fr;gap:.2em}
  .occ-more__grid{grid-template-columns:1fr}
  .occ-step--all,.occ-step--next{text-align:left}
}

/* the hub and the occasion finder: one card shape, the panel above its name */
.occ-group{margin-top:clamp(40px,5vw,72px)}
.occ-group__head{display:flex;justify-content:space-between;align-items:baseline;gap:1em;flex-wrap:wrap;
  border-top:1px solid var(--rule-light);padding-top:18px;margin-bottom:clamp(20px,2.4vw,32px)}
.occ-group__head h2{margin:0}
.occ-group__head p{margin:0;color:var(--grey);font-size:clamp(13px,.95vw,15px)}
.occ-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(20px,2.4vw,36px) clamp(14px,1.8vw,28px)}
@media (max-width:999px){.occ-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.occ-grid{grid-template-columns:1fr}}
.occ-card{display:block;text-decoration:none;color:inherit}
.occ-card__pic{display:block;aspect-ratio:3/2;overflow:hidden;background:#1b1d33}
.occ-card__pic img{width:100%;height:100%;object-fit:cover;transition:transform .9s cubic-bezier(.2,.7,.2,1)}
.occ-card:hover .occ-card__pic img,.occ-card:focus-visible .occ-card__pic img{transform:scale(1.03)}
.occ-card__name{display:block;margin:.75em 0 .2em;font-size:clamp(18px,1.4vw,22px);font-weight:500}
.occ-card:hover .occ-card__name{text-decoration:underline;text-underline-offset:5px;text-decoration-thickness:1px}
.occ-card__line{display:block;color:var(--grey);font-size:clamp(14px,1vw,15.5px);line-height:1.45}
.occ-card__date{display:block;margin-top:.5em;font-size:12px;letter-spacing:.14em;text-transform:uppercase}
.sheet--ink .occ-card__line{color:var(--metal)}

/* about */
.about-cols{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);gap:clamp(28px,4vw,72px);align-items:start}
.about-cols .lede{margin-top:0}
@media (max-width:860px){.about-cols{grid-template-columns:1fr}}
.route{list-style:none;padding:0;margin:0 0 clamp(18px,2vw,28px);display:grid;grid-template-columns:repeat(3,minmax(0,1fr));counter-reset:r}
.route--direct{grid-template-columns:repeat(3,minmax(0,1fr))}
.route li{position:relative;padding:22px 28px 22px 0;border-top:1px solid var(--metal)}
.route li::before{content:"";position:absolute;top:-5px;left:0;width:9px;height:9px;border-radius:50%;background:var(--paper)}
.route li:not(:last-child)::after{content:"";position:absolute;top:-5px;right:14px;width:9px;height:9px;
  border-top:1px solid var(--metal);border-right:1px solid var(--metal);transform:rotate(45deg)}
.route b{display:block;font-weight:500;font-size:clamp(17px,1.3vw,20px);margin-bottom:.3em}
.route span{color:var(--metal);font-size:clamp(14px,1vw,15.5px)}
@media (max-width:760px){
  .route,.route--direct{grid-template-columns:1fr}
  .route li{border-top:0;border-left:1px solid var(--metal);padding:0 0 22px 22px}
  .route li::before{top:4px;left:-5px}
  .route li:not(:last-child)::after{top:auto;bottom:6px;right:auto;left:-5px;transform:rotate(135deg)}
}
.about-made p:last-child a{white-space:nowrap}
.about-measure{margin-top:2em;padding-top:1.2em;border-top:1px solid var(--rule-light);max-width:var(--measure)}

/* contact */
.contact-grid{display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);gap:clamp(28px,5vw,88px);align-items:start}
.contact-card{position:sticky;top:calc(var(--mh) + 24px);margin-top:clamp(56px,6vw,96px)}
@media (max-width:860px){.contact-grid{grid-template-columns:1fr}.contact-card{position:static;margin-top:0}}

/* the church-year guide: a light, dated timeline (BUILD_SPEC §7) */
.guide-head{padding-bottom:clamp(20px,2.4vw,36px)}
.picker{display:flex;flex-wrap:wrap;gap:8px;margin-top:clamp(20px,2.4vw,32px)}
.picker button{font:inherit;font-size:14px;letter-spacing:.02em;padding:10px 16px;min-height:44px;border:1px solid var(--rule-light);
  background:transparent;color:var(--ink);cursor:pointer;border-radius:0}
.picker button:hover{border-color:var(--ink)}
.picker button[aria-pressed="true"]{background:var(--ink);color:var(--paper);border-color:var(--ink)}
.guide-page[data-trad="rc"] .trad--guide div:not([data-trad="rc"]),
.guide-page[data-trad="ang"] .trad--guide div:not([data-trad="ang"]),
.guide-page[data-trad="lut"] .trad--guide div:not([data-trad="lut"]),
.guide-page[data-trad="met"] .trad--guide div:not([data-trad="met"]){display:none}
.guide-line{padding-top:0}
.opener{margin:0 0 clamp(10px,1.2vw,16px);padding:14px 0;border-top:1px solid var(--rule-light);
  color:var(--grey);font-size:clamp(14px,1vw,15.5px)}
.opener b{color:var(--ink);font-weight:500}
.seasons{display:grid;gap:0}
.season-card{display:grid;grid-template-columns:minmax(0,15rem) minmax(0,1.35fr) minmax(0,1fr);gap:clamp(20px,2.8vw,48px);
  padding:clamp(28px,3.2vw,48px) 0;border-top:1px solid var(--rule-light);scroll-margin-top:calc(var(--mh) + 16px)}
.season-card:last-child{border-bottom:1px solid var(--rule-light)}
.season-card__when{position:relative;padding-left:18px}
.season-card__when .sw{position:absolute;left:0;top:4px;bottom:4px;width:6px;background:var(--sw);
  box-shadow:inset 0 0 0 1px rgba(11,11,12,.14)}
.season-card .when{margin:0 0 14px;font-size:clamp(14px,1vw,15.5px);letter-spacing:.02em}
.season-card__pic{display:block;aspect-ratio:3/2;overflow:hidden}
.season-card__pic img{width:100%;height:100%;object-fit:cover;transition:transform .9s cubic-bezier(.2,.7,.2,1)}
.season-card__pic:hover img{transform:scale(1.03)}
.season-card h2{margin:0 0 .3em}
.season-card .meaning{margin:0 0 1.1em;max-width:52ch}
.trad--guide div{grid-template-columns:minmax(0,12em) minmax(0,1fr)}
.days--in{margin-top:1.1em}
.days--in li{display:block;font-size:.94em}
.days--in li span{display:block;text-align:left;margin-top:.15em}
.season-card .source{margin-top:1em}
.season-card__stoles .of{margin:0 0 12px;font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--grey)}
.minis{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-bottom:1.2em}
.mini{display:block;text-decoration:none;color:inherit}
.mini img{width:100%;height:auto;aspect-ratio:2/3;object-fit:cover;background:#2b2b2b}
.mini span{display:block;margin-top:.5em;font-size:13px;line-height:1.3}
.mini b{display:block;font-weight:500;font-size:13px;margin-top:.15em}
.mini:hover span{text-decoration:underline;text-underline-offset:3px}
.season-card.is-past{opacity:.5}
.season-card.is-past h2::after{content:" (past)";font-size:.5em;letter-spacing:.14em;text-transform:uppercase;color:var(--grey)}
.guide-line .is-past b{text-decoration:line-through}
@media (max-width:999px){
  .season-card{grid-template-columns:minmax(0,13rem) minmax(0,1fr)}
  .season-card__stoles{grid-column:1 / -1}
  .minis{grid-template-columns:repeat(3,minmax(0,170px))}
}
@media (max-width:640px){
  .season-card{grid-template-columns:1fr}
  .season-card__when{padding-left:14px}
  .season-card__pic{max-width:none}
  .trad--guide div{grid-template-columns:1fr;gap:.15em}
  .minis{grid-template-columns:repeat(3,minmax(0,1fr))}
}
.guide-full{border-top:1px solid var(--rule-light)}
.fold{border-top:1px solid var(--rule-light)}
.fold:last-of-type{border-bottom:1px solid var(--rule-light)}
.fold summary{cursor:pointer;list-style:none;padding:18px 0;font-size:clamp(18px,1.4vw,22px);display:flex;justify-content:space-between;align-items:center;min-height:44px}
.fold summary::-webkit-details-marker{display:none}
.fold summary::after{content:"+";font-size:1.2em;color:var(--grey);transition:transform .3s ease}
.fold[open] summary::after{transform:rotate(45deg)}
.fold .tablewrap{margin-top:4px}

/* the shop's filters (Sol 18) */
.shop-note{color:var(--metal);margin:-.6em 0 1.6em;max-width:var(--measure)}
.filters{display:flex;flex-wrap:wrap;justify-content:space-between;align-items:end;gap:16px 28px;margin:0 0 clamp(28px,3vw,44px);
  padding:16px 0;border-top:1px solid var(--rule-dark);border-bottom:1px solid var(--rule-dark)}
.filters[hidden]{display:none}
.ftabs{display:flex;flex-wrap:wrap;gap:6px}
.ftab{padding:10px 14px;min-height:44px;display:inline-flex;align-items:center;border:1px solid var(--rule-dark);text-decoration:none;font-size:14px}
.ftab:hover{border-color:var(--metal)}
.ftab[aria-current="true"]{background:var(--paper);color:var(--ink) !important;border-color:var(--paper)}
.fsel{display:flex;flex-wrap:wrap;align-items:end;gap:12px 18px}
.fsel label{display:flex;flex-direction:column;gap:4px;font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--metal)}
.fsel select{font:inherit;font-size:15px;letter-spacing:0;text-transform:none;min-height:44px;padding:8px 34px 8px 12px;background:var(--ink);
  color:var(--paper);border:1px solid var(--rule-dark);border-radius:0;-webkit-appearance:none;appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--metal) 50%),linear-gradient(135deg,var(--metal) 50%,transparent 50%);
  background-position:calc(100% - 17px) 50%,calc(100% - 12px) 50%;background-size:5px 5px;background-repeat:no-repeat}
.fcount{margin:0 0 10px;color:var(--metal);font-size:14px;min-width:6em}
.shop .card[hidden],.shop .coll[hidden]{display:none}
.fempty{color:var(--metal)}
.fempty button{font:inherit;background:none;border:0;border-bottom:1px solid currentColor;color:var(--paper);cursor:pointer;padding:0}
@media (max-width:760px){.filters{flex-direction:column;align-items:stretch}.fsel label{flex:1 1 140px}.fsel select{width:100%}}

/* the product page: name and price BEFORE the gallery on a phone (Astra 17 + Sol), the buying block first on desktop */
.product .stole-hero{grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);grid-template-areas:"gallery title" "gallery text";grid-template-rows:auto 1fr}
.product .stole-hero__title{grid-area:title}
.product .gallery{grid-area:gallery;position:sticky;top:calc(var(--mh) + 20px)}
.product .stole-hero__text{grid-area:text}
.product .stole-hero__title .of{margin:0 0 .9em;font-size:clamp(10px,0.76vw,12px);letter-spacing:.2em;text-transform:uppercase;color:var(--metal)}
.product .stole-hero__title h1{margin:0 0 .3em}
.product .stole-hero__title .price{margin:0 0 .3em}
.render-note{margin:.8em 0 0;font-size:13px;color:var(--metal)}
.product .free{margin:.6em 0 0}
/* two columns down to a tablet held upright (768): Add to cart stays on the first screen there (check_directions) */
.product .stole-hero{grid-template-columns:minmax(0,1.05fr) minmax(0,1fr) !important}
@media (max-width:760px){
  .product .stole-hero{grid-template-columns:1fr !important;grid-template-areas:"title" "gallery" "text";grid-template-rows:auto}
  .product .gallery{position:static}
}
/* ⛔ 2026-10-27 (the store walk could not click a thumbnail): the gallery stuck to the top of the window while being TALLER
   than it (1029 px in a 900 px window), so the four other pictures sat below the screen until ~1000 px of scrolling (1600 at
   1280x720) and a shopper reading the price never saw them. On a wide screen the pictures now run down a slim column
   beside the main one, and the main one is sized to the window, so the whole gallery is always on screen (check_directions
   measures it at seven window sizes). Phones and upright tablets keep the row underneath: a phone's gallery is not sticky,
   and on an upright tablet the gallery already fits (the column would only shrink the picture there). */
@media (min-width:761px) and (min-aspect-ratio:1/1){
  .product .gallery{display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:10px;align-items:start}
  .product .gallery .main{grid-column:2;grid-row:1;justify-self:start;width:min(100%, calc((100svh - var(--mh) - 40px) * 2 / 3));height:auto}
  .product .thumbs{grid-column:1;grid-row:1;display:flex;flex-direction:column;gap:8px;margin-top:0}
  .product .thumb{width:min(64px, calc((100svh - var(--mh) - 72px) / 5 * 2 / 3))}
}

/* the homepage below the rooms (BUILD_SPEC §4) */
.intro-grid{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:clamp(32px,5vw,96px);align-items:start}
.intro .of{margin:0 0 14px;font-size:12px;letter-spacing:.2em;text-transform:uppercase;color:var(--metal)}
.prop{font-size:clamp(34px,4.4vw,64px);line-height:1.04;max-width:13ch;margin:0 0 .45em}
.coming .days{border-top-color:var(--rule-dark)}
.coming-list li{padding:0;border-bottom-color:var(--rule-dark)}
.coming-list a{display:flex;gap:18px;align-items:center;padding:14px 0;text-decoration:none;width:100%}
.coming-list .cd{flex:0 0 56px;display:flex;flex-direction:column;align-items:center;justify-content:center;height:62px;
  border:1px solid var(--rule-dark);font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--metal)}
.coming-list .cd b{font-size:24px;font-weight:400;letter-spacing:0;color:var(--paper);line-height:1}
.coming-list .cu{display:flex;flex-direction:column;gap:2px;text-align:left}
.coming-list .cu b{font-weight:400;font-size:clamp(17px,1.25vw,20px);color:var(--paper)}
.coming-list .cu span{color:var(--metal);font-size:14px;text-align:left}
.coming-list a:hover .cd{border-color:var(--paper)}
.coming-list a:hover .cu b{text-decoration:underline;text-underline-offset:4px}
@media (max-width:860px){.intro-grid{grid-template-columns:1fr}}
.finder .occ-grid--home{grid-template-columns:repeat(4,minmax(0,1fr))}
.finder .occ-card__date{color:var(--metal)}
.finder-more{margin-top:clamp(28px,3vw,44px)}
@media (max-width:999px){.finder .occ-grid--home{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:760px){.finder .occ-grid--home{grid-template-columns:repeat(2,minmax(0,1fr));gap:22px 12px}
  .finder .occ-card__line{display:none}}
.compare{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(18px,2.4vw,40px)}
.cmp img{width:100%;height:auto;aspect-ratio:4/5;object-fit:cover;object-position:50% 70%;background:#2b2b2b}
.cmp h3{margin:.9em 0 .1em;font-size:clamp(20px,1.6vw,26px)}
.cmp-price{margin:0 0 .6em;color:var(--metal)}
.cmp .spec{margin:0 0 1.2em}
.measure-strip{display:grid;grid-template-columns:120px minmax(0,1fr);gap:24px;align-items:center;margin-top:clamp(36px,4vw,56px);
  padding-top:24px;border-top:1px solid var(--rule-dark)}
.measure-strip img{width:120px;height:auto;aspect-ratio:2/3;object-fit:cover;background:#2b2b2b}
.measure-strip p{margin:0;color:var(--metal);max-width:var(--measure)}
.measure-strip b{color:var(--paper);font-weight:400}
@media (max-width:860px){.compare{grid-template-columns:1fr}.cmp img{aspect-ratio:3/2}}
.sizes-grid{display:grid;grid-template-columns:minmax(0,1.6fr) minmax(0,1fr);gap:clamp(28px,5vw,88px);align-items:start}
.sizes-art{margin:0;position:sticky;top:calc(var(--mh) + 24px)}
.sizes-art img{width:100%;height:auto;background:#2b2b2b}
/* pinned while the page scrolls, so it must fit the window (check_fit.js; it ran 12 px past a 1280x720 window, 10-27) */
@media (min-width:861px){.sizes-art img{width:auto;max-width:100%;max-height:calc(100svh - var(--mh) - 48px)}}
.sizes-art .render-note{color:var(--grey)}
@media (max-width:860px){.sizes-grid{grid-template-columns:1fr}.sizes-art{position:static;max-width:360px}}

.cmp .spec div{display:block;padding:.55em 0}
.cmp .spec dt{font-size:11px;letter-spacing:.16em;text-transform:uppercase;color:var(--metal)}
.cmp .spec dd{text-align:left;margin:.15em 0 0}
.product .stole-hero{row-gap:clamp(10px,1.2vw,20px)}
.opener a{margin-left:.4em;color:var(--ink)}
.menu .m-close{display:none}
.menu[open] .m-open{display:none}
.menu[open] .m-close{display:inline}

/* ⛔ 2026-10-26 (check_calm, Simple cross room): with the header now sticky above the rooms, a jump to #simple-cross
   scrolled the room up by the header's height and the header covered "Back to all stoles" and "Play tour". Every jump
   target leaves room for the header; a room lands exactly under it. */
[id]{scroll-margin-top:calc(var(--mh) + 12px)}
.opening[id]{scroll-margin-top:var(--mh)}

/* the four promises' line icons (code-drawn) */
.confidence--wide .ci{display:block;width:30px;height:30px;margin:0 0 12px;fill:none;stroke:var(--metal);stroke-width:1.25;
  stroke-linecap:round;stroke-linejoin:round}
.occ-links{margin:1em 0;color:var(--metal);font-size:15px}
.occ-links a{color:var(--paper)}
.cart-note{margin-top:1.6em}

/* review round 1 (Astra): the render disclosure sits WITH the pictures it describes */
.stole-hero__plate.main{position:relative}
.render-tag{position:absolute;left:10px;bottom:10px;margin:0;padding:4px 8px;font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--paper);background:rgba(11,11,12,.72);pointer-events:none}
.doors .room-render{display:block;margin-top:10px;font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--metal);opacity:.85}
.shelf-render{margin:0 auto 0 0;order:-1}
.shelf-nav{display:flex;align-items:center;gap:10px}
.sheet--ink .render-note{color:var(--metal)}
.days .dcol{display:block;font-size:.92em}
.days .dcol a{color:inherit}
.season-note{margin:-.4em 0 1em}

/* review round 1 (Astra 17): on a phone the shop shows a whole card, with its price, on the first screen */
@media (max-width:760px){
  .shop-page .shop{padding-top:22px}
  .shop-page .head{margin-bottom:12px;padding-top:12px}
  .shop-page .head .of{margin-bottom:8px}
  .shop-page h1{font-size:28px}
  .shop-note{margin:0 0 12px;font-size:14px;line-height:1.45}
  .filters{padding:10px 0;margin-bottom:14px;gap:10px}
  .ftabs{flex-wrap:nowrap;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;margin:0 calc(-1 * var(--edge));padding:0 var(--edge)}
  .ftabs::-webkit-scrollbar{display:none}
  .ftab{flex:0 0 auto;padding:8px 12px}
  .fsel{display:grid;grid-template-columns:1fr 1fr;gap:8px}
  .fsel label span{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  .fsel select{font-size:14px;padding:8px 28px 8px 10px}
  .fcount{display:none}
  .shop .coll-head{padding-top:12px;margin-bottom:12px}
  .shop .coll-head h2{font-size:22px}
  .shop .coll-head p{font-size:13px}
}

/* the guide's picker hides the stoles a tradition does not wear that season */
.guide-page[data-trad="rc"] .mini[data-trads]:not([data-trads~="rc"]),
.guide-page[data-trad="ang"] .mini[data-trads]:not([data-trads~="ang"]),
.guide-page[data-trad="lut"] .mini[data-trads]:not([data-trads~="lut"]),
.guide-page[data-trad="met"] .mini[data-trads]:not([data-trads~="met"]){display:none}

/* the phone buy bar (Sol 14) */
.buybar{position:fixed;left:0;right:0;bottom:0;z-index:30;display:flex;align-items:center;gap:12px;padding:10px var(--edge)
  calc(10px + env(safe-area-inset-bottom));background:rgba(11,11,12,.96);border-top:1px solid var(--rule-dark);color:var(--paper)}
.buybar[hidden]{display:none}
.buybar .bb-name{flex:1 1 auto;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.buybar .bb-add{flex:0 0 auto;font:inherit;font-size:13px;letter-spacing:.12em;text-transform:uppercase;padding:12px 16px;min-height:44px;
  background:var(--paper);color:var(--ink);border:0;cursor:pointer}
.buybar .bb-done{flex:0 0 auto;font-size:14px;color:var(--paper)}
.buybar .bb-done[hidden],.buybar .bb-add[hidden]{display:none}
/* the count keeps its space on a phone, where the link is a flex box and would swallow it */
.cartlink .cart-n:not(:empty){margin-left:.35em}
@media (max-width:760px){body:has(.buybar:not([hidden])) .foot{padding-bottom:96px}}
.render-line{margin:0 0 .6em;font-size:13px;color:var(--metal)}
.season-card__stoles .render-note{margin:-.4em 0 1em;font-size:12px;color:var(--grey)}

/* ================================================================ the passing shadow (2026-10-27, Astra + Sol, atelier.js)
   Three rooms wide: a soft edge one room wide, an opaque warm-charcoal middle exactly one room wide, a soft edge. It sits
   over the picture area only (the tabs, caption and buttons stay above it) and waits off-screen until a switch. */
.room-shadow-clip{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:6}
.room-shadow{position:absolute;top:0;bottom:0;left:0;width:300%;transform:translateX(-100%);will-change:transform;
  background:linear-gradient(90deg,rgba(9,8,7,0) 0%,rgba(9,8,7,.55) 16%,rgba(9,8,7,.92) 28%,#090807 33.34%,
    #090807 66.66%,rgba(9,8,7,.92) 72%,rgba(9,8,7,.55) 84%,rgba(9,8,7,0) 100%)}
.opening--camera .tabs .tab.is-preparing{opacity:.7}
.opening--camera .tabs .tab.is-preparing::after{content:"";width:6px;height:6px;margin-left:8px;border-radius:50%;background:currentColor;
  animation:fog-prep 1s ease-in-out infinite}
@keyframes fog-prep{0%,100%{opacity:.25}50%{opacity:1}}

/* the tour shows that it runs (2026-10-27): where it is, a progress line, what comes next, Pause and Next */
.opening--camera .calm{flex-wrap:wrap;justify-content:flex-end;row-gap:6px}
.opening--camera .tourbar,.opening--camera .tourend{flex-basis:100%;display:flex;align-items:center;justify-content:flex-end;gap:12px;
  color:var(--paper);font-size:13px;letter-spacing:.04em;padding:2px 0 6px}
.opening--camera .tourbar[hidden],.opening--camera .tourend[hidden]{display:none}
.opening--camera .tb-count{white-space:nowrap}
.opening--camera .tb-track{position:relative;width:92px;height:2px;background:rgba(244,243,241,.22);overflow:hidden}
.opening--camera .tb-fill{position:absolute;inset:0;background:var(--paper);transform:scaleX(0);transform-origin:left center}
.opening--camera .tb-next{color:var(--metal);white-space:nowrap}
.opening--camera .tb-ctl{display:flex;gap:4px}
.opening--camera .tourbar button,.opening--camera .tourend button,.opening--camera .tourend a{font:inherit;font-size:12px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--paper);background:none;border:1px solid rgba(244,243,241,.35);padding:6px 10px;min-height:32px;
  cursor:pointer;text-decoration:none;display:inline-flex;align-items:center}
.opening--camera .tourbar button:hover,.opening--camera .tourend button:hover,.opening--camera .tourend a:hover{border-color:var(--paper)}
.opening--camera .tourend span{color:var(--metal)}
@media (max-width:760px), (max-aspect-ratio:6/5){
  .opening--camera .tourbar,.opening--camera .tourend{flex-wrap:wrap;justify-content:flex-end;gap:8px;font-size:12px}
  .opening--camera .tb-next{display:none}
}

/* both reviewers: the room's own large FOGRIO duplicated the header's and sat over the first robe. It stays for readers
   (the page's heading) but is no longer drawn over the stoles. ⛔ display:block is required: a desktop rule sets the head
   to display:contents, which has no box of its own, so the clip below did nothing and the mark stayed (seen 10-27). */
.opening.opening--carousel.opening--camera .plate-head{display:block;position:absolute;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;padding:0}

/* custom orders (2026-10-27) */
.custom-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(28px,5vw,88px);align-items:start}
.custom-intro .lede{margin-top:0}
.custom-steps{list-style:none;counter-reset:cs;padding:0;margin:clamp(20px,2.4vw,32px) 0;border-top:1px solid var(--rule-light)}
.custom-steps li{counter-increment:cs;display:grid;grid-template-columns:2.2em minmax(0,1fr);column-gap:.6em;padding:14px 0;border-bottom:1px solid var(--rule-light)}
.custom-steps li::before{content:counter(cs);grid-row:1 / span 2;font-size:22px;line-height:1.1;color:var(--grey)}
.custom-steps b{font-weight:500}
.custom-steps span{color:var(--grey)}
.custom-form{margin-top:clamp(0px,4vw,96px)}
.field-row{display:grid;grid-template-columns:minmax(0,9em) minmax(0,1fr);gap:16px}
.custom-nudge{font-size:14px;color:var(--metal);margin-top:.4em}
.custom-nudge a{color:var(--paper)}
.shop-note a{color:var(--paper)}
@media (max-width:860px){.custom-grid{grid-template-columns:1fr}.custom-form{margin-top:0}}
