/* ===========================================================================
   FASHION CASTING — foundations for the full-site build.
   README 5.0 §7 (tokens) and §5.0 (shared chrome). PDF order of work, step 1.

   This file carries the things the whole site shares: the two self-hosted
   faces, the type scale, the glass recipe, the primitives (button, panel,
   pill, door tile, field, chip) and the interior header/footer chrome.

   WHY THE FONTS ARE SELF-HOSTED. The prototype's fonts.css pulls Montserrat
   from jsDelivr. This site loads no third-party JavaScript at all and takes
   money on /payments — a CDN in the critical path of a payment page is a
   supply-chain risk it does not currently carry. README §9 asks for
   self-hosting anyway. Both faces sit in assets/fonts/.

   NOTE ON RADII (§7): the identity is hard-edged — buttons and inputs are
   2px, cards 4px, and 999px is reserved for pills. Glass surfaces break that
   deliberately (24px panels, 22px door cards, 18px sub-cards). Do not
   "tidy" one into the other.
=========================================================================== */

/* --- the two faces ------------------------------------------------------ */

@font-face {
  font-family: "Montserrat";
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;                 /* variable: 200 for display, 300 everywhere else */
  src: url("assets/fonts/montserrat-latin-wght-normal.woff2") format("woff2-variations");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
                 U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+2074, U+20AC,
                 U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Bodoni survives in exactly one place: the "FC" monogram. */
@font-face {
  font-family: "Bodoni Moda";
  font-style: normal;
  font-display: swap;
  font-weight: 400;
  src: url("assets/fonts/bodoni-moda-latin-400-normal.woff2") format("woff2");
  unicode-range: U+0000-00FF;
}

:root {
  --font-sans: "Montserrat", "Avenir Next", "Segoe UI", system-ui, -apple-system, sans-serif;
  --font-serif-display: "Bodoni Moda", "Didot", "Bodoni MT", serif;
  --font-body: var(--font-sans);
  --font-display: var(--font-sans);     /* §7: every heading is Montserrat 300 */
  --font-monogram: var(--font-serif-display);

  --fc-ground: #011a11;
  --fc-header-glass: rgba(2, 54, 35, .74);
  --fc-ivory: #f6f0e4;
  --fc-accent: #c2e0d1;
  --fc-danger: #9e2b25;

  --fc-hairline: rgba(246, 240, 228, .14);
  --fc-hairline-strong: rgba(246, 240, 228, .28);
  --fc-glass: rgba(246, 240, 228, .06);
  --fc-glass-hover: rgba(246, 240, 228, .13);
  --fc-locked-dim: rgba(1, 26, 17, .62);

  --header-height: 72px;
  --fc-section-y: 96px;
  --fc-container: 1200px;

  --fc-ease-standard: cubic-bezier(.2, .6, .2, 1);
  --fc-ease-out: cubic-bezier(0, 0, .2, 1);
  --fc-ease-in: cubic-bezier(.4, 0, 1, 1);
}

/* --- type scale (§7) ----------------------------------------------------- */

.fc-display-1 { font: 300 clamp(38px, 4.6vw, 68px)/1.04 var(--font-display); letter-spacing: -.005em; }
.fc-display-2 { font: 300 clamp(32px, 3.8vw, 56px)/1.06 var(--font-display); letter-spacing: -.005em; }
.fc-h1        { font: 300 clamp(27px, 2.9vw, 42px)/1.1  var(--font-display); letter-spacing: -.005em; }
.fc-h2        { font: 300 clamp(22px, 2.1vw, 30px)/1.15 var(--font-display); letter-spacing: -.005em; }
.fc-h3        { font: 300 clamp(19px, 1.7vw, 25px)/1.2  var(--font-display); letter-spacing: -.005em; }
.fc-h4        { font: 500 18px/1.36 var(--font-display); }

.fc-body-lg   { font: 300 18px/1.62 var(--font-body); }
.fc-body      { font: 300 16px/1.65 var(--font-body); }
.fc-body-sm   { font: 300 14px/1.6  var(--font-body); }
.fc-caption   { font: 300 12px/1.5  var(--font-body); letter-spacing: .01em; }
.fc-eyebrow   { font: 600 11px/1 var(--font-body); letter-spacing: .18em; text-transform: uppercase; }
.fc-label     { font: 600 13px/1.3 var(--font-body); }

/* Indices and counts are tabular so columns of numbers line up. */
.fc-num { font-variant-numeric: tabular-nums lining-nums; }

.fc-muted  { color: rgba(246, 240, 228, .60); }
.fc-second { color: rgba(246, 240, 228, .72); }
.fc-faint  { color: rgba(246, 240, 228, .45); }
.fc-accent { color: var(--fc-accent); }

/* --- layout -------------------------------------------------------------- */

.fc-container {
  width: 100%;
  max-width: var(--fc-container);
  margin-inline: auto;
  padding-inline: 24px;
  box-sizing: border-box;
}
@media (min-width: 900px) { .fc-container { padding-inline: 40px; } }

.fc-section { padding-block: var(--fc-section-y); }
.fc-section--compact { padding-block: 64px; }

/* --- glass (§7 recipe) --------------------------------------------------- */

.fc-glass {
  position: relative;
  background: var(--fc-glass);
  border: 1px solid rgba(246, 240, 228, .18);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .22);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  border-radius: 24px;
}
/* The specular top edge that makes glass read as glass. */
.fc-glass::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, rgba(246, 240, 228, .48), transparent);
  pointer-events: none;
}
/* Where backdrop-filter is unsupported the panel must not become a pale
   rectangle on the green — it falls back to near-solid ground (§7). */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .fc-glass { background: rgba(1, 26, 17, .92); }
}

/* --- primitives ---------------------------------------------------------- */

.fc-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;                      /* §6: touch targets >= 44px */
  padding: 0 22px;
  border-radius: 2px;                    /* hard-edged identity */
  border: 1px solid transparent;
  font: 600 11px/1 var(--font-body);
  letter-spacing: .18em;
  text-transform: uppercase;
  cursor: pointer;
  text-decoration: none;
  transition: background-color 200ms var(--fc-ease-standard),
              color 200ms var(--fc-ease-standard),
              transform 140ms var(--fc-ease-standard),
              border-color 200ms var(--fc-ease-standard);
}
.fc-btn:active { transform: scale(.985); }
.fc-btn--lg { min-height: 48px; padding: 0 28px; }
.fc-btn--sm { min-height: 38px; padding: 0 16px; }
.fc-btn--block { width: 100%; }

.fc-btn--primary { background: var(--fc-ivory); color: var(--fc-ground); border-color: var(--fc-ivory); }
.fc-btn--primary:hover { background: #fff; color: var(--fc-ground); }

.fc-btn--secondary {
  background: rgba(246, 240, 228, .06);
  color: var(--fc-ivory);
  border-color: rgba(246, 240, 228, .28);
  backdrop-filter: blur(16px) saturate(160%);
  -webkit-backdrop-filter: blur(16px) saturate(160%);
}
.fc-btn--secondary:hover { background: rgba(246, 240, 228, .13); color: #fff; }

.fc-pill {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 16px;
  border-radius: 999px;
  border: 1px solid rgba(246, 240, 228, .22);
  background: rgba(246, 240, 228, .07);
  font: 300 14px/1.4 var(--font-body);
  color: var(--fc-ivory);
}

/* Fields are a rule underneath, never a rectangle around. */
.fc-field {
  width: 100%;
  box-sizing: border-box;
  padding: 11px 2px;
  border: 0;
  border-bottom: 1px solid rgba(246, 240, 228, .22);
  background: transparent;
  font: 300 15px/1.4 var(--font-body);
  color: var(--fc-ivory);
  outline: none;
  transition: border-color 300ms var(--fc-ease-standard);
}
.fc-field::placeholder { color: rgba(246, 240, 228, .3); }
.fc-field:focus { border-bottom-color: var(--fc-accent); }
.fc-field[aria-invalid="true"] { border-bottom-color: var(--fc-danger); }
/* iOS zooms the page when a focused field is under 16px. The design calls
   for 15px, which is right with a pointer and a trap on a phone. */
@media (pointer: coarse) { .fc-field { font-size: 16px; } }

.fc-chip {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: 10px;
  padding: 11px 17px;
  border: 1px solid rgba(246, 240, 228, .24);
  border-radius: 999px;
  cursor: pointer;
  transition: border-color 250ms var(--fc-ease-standard),
              background-color 250ms var(--fc-ease-standard);
}
.fc-chip:hover { border-color: rgba(246, 240, 228, .44); background: rgba(246, 240, 228, .04); }
.fc-chip input { width: 16px; height: 16px; accent-color: var(--fc-accent); }

/* Keyboard focus must be visible everywhere (§7 focus ring). */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(246, 240, 228, .45);
  border-radius: 2px;
}

/* --- interior header (§5.0) ---------------------------------------------- */


.fc-nav { display: flex; align-items: center; gap: 24px; margin-left: auto; }
.fc-nav a {
  font: 300 14px/1 var(--font-body);
  color: rgba(246, 240, 228, .6);
  text-decoration: none;
  white-space: nowrap;
  transition: color 200ms var(--fc-ease-standard);
}
.fc-nav a:hover { color: var(--fc-ivory); }
.fc-nav a[aria-current="page"] { color: var(--fc-ivory); }

/* Below the desktop breakpoint the text nav would overflow; it collapses to
   the lockup plus the primary action, which is the only one that must
   survive on a phone. */
@media (max-width: 1099px) { .fc-nav { display: none; } }

/* --- the bracket lockup -------------------------------------------------- */

.fc-lockup { position: relative; display: flex; align-items: center; justify-content: center; flex: none; }
.fc-lockup span[data-corner] { position: absolute; width: 14px; height: 14px; }
.fc-lockup .fc-monogram {
  font-family: var(--font-monogram);
  font-weight: 400;
  line-height: 1;
  letter-spacing: .03em;
  color: var(--fc-ivory);
}
.fc-wordmark {
  font: 300 clamp(12px, 1.1vw, 15px)/1 var(--font-body);
  letter-spacing: .34em;
  padding-left: .34em;
  color: var(--fc-ivory);
  white-space: nowrap;
}

/* --- shared keyframes (§7) ----------------------------------------------- */

@keyframes cfDoorIn  { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes cfRise    { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: none; } }
@keyframes cfRule    { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes cfSheen   { 0% { background-position: -120% 0; } 100% { background-position: 220% 0; } }
@keyframes cfGlassBreathe { 0%, 100% { background-color: rgba(246,240,228,0); } 50% { background-color: rgba(246,240,228,.022); } }
@keyframes cfLiquid {
  0%   { transform: translate3d(0%, 0%, 0) scale(1); }
  33%  { transform: translate3d(70%, 12%, 0) scale(1.25); }
  66%  { transform: translate3d(140%, -8%, 0) scale(.95); }
  100% { transform: translate3d(0%, 0%, 0) scale(1); }
}

/* --- scroll reveal (§5.5) ------------------------------------------------ */

/* Everything must be readable with JS off, so the hidden state is applied
   only once the observer has claimed the element (data-reveal="armed"). */
[data-reveal="armed"] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity 520ms var(--fc-ease-out), transform 520ms var(--fc-ease-out);
}
[data-reveal="in"] { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal="armed"] { opacity: 1; transform: none; transition: none; }
  *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; }
}

/* ---------------------------------------------------------------------------
   PHOTOGRAPH PLACEHOLDERS  (31 Aug 2026)

   README §3 and the PDF both say the same thing: no photography ships with
   this design, and every image position is a placeholder until real,
   consented, rights-cleared pictures exist. The Unsplash stock that had been
   standing in was removed on 31 Aug; these hold the exact boxes it occupied
   so no hero collapses and no layout moves when the real frames arrive.

   Deliberately NOT a grey box. It is the house ground with the same scrim a
   photographic plate carries, so a page with no pictures still reads as the
   house rather than as a broken build.

   To wire a real photograph: replace the <div data-photo-slot> with an <img>
   carrying the same width/height, and delete nothing else.
--------------------------------------------------------------------------- */
.fc-photo-slot,
[data-photo-slot] {
  background:
    radial-gradient(72% 60% at 50% 38%, rgba(19, 125, 82, .16), rgba(1, 26, 17, 0) 70%),
    linear-gradient(180deg, #02180F 0%, #02150E 52%, #01120B 100%);
  pointer-events: none;
  display: block;
  width: 100%;
}

/* In a photographic plate the slot sits behind the type, filling the frame.
   inset:0 alone (no height:100%) so the frame's own min-height governs — a
   height:100% against an auto-height parent resolves to the aspect-ratio and
   produced a 2,500px hero. */
[data-plate] > [data-photo-slot] {
  position: absolute;
  inset: 0;
  z-index: 0;
  aspect-ratio: auto !important;
}

/* THE PLATE'S OWN GEOMETRY.
   site-lattice.css carries these for the four pages that link it, but
   Modelboard never did — it was relying entirely on the photograph for its
   height, so removing the stock image collapsed the hero to 106px. Repeated
   here at identical values so a plate is correct on any page. */
[data-plate] {
  position: relative;
  isolation: isolate;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: clamp(320px, 62svh, 620px);
  width: 100%;
  overflow: hidden;
  background: #02150E;
}
[data-plate]::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(180deg, rgba(2,21,14,.72) 0%, rgba(2,21,14,.30) 34%,
                            rgba(2,21,14,.30) 66%, rgba(2,21,14,.78) 100%),
    radial-gradient(58% 52% at 50% 50%, rgba(2,21,14,.42) 0%, rgba(2,21,14,0) 70%);
  pointer-events: none;
}
[data-plate] > [data-plate-copy] { position: relative; z-index: 2; }

/* A hero <figure> whose only child was the photograph keeps its height from
   the slot's aspect-ratio instead. */
figure > .fc-photo-slot,
figure > [data-photo-slot] { position: relative; }

/* --- the shared chrome elements ------------------------------------------
   The header was a flat 72px bar before the design moved to the floating
   pill. That rule survived the rewrite and kept giving the host a solid
   glass background, a fixed height AND a hairline along its bottom edge —
   which drew a line straight across the hero photograph. The pill carries
   its own border; the host must carry none. */
fc-footer { display: block; }

/* ---------------------------------------------------------------------------
   THE DOOR GRID  (README 5.0 §5.2)

   Nine doors, centred, on the page ground — no card, no corner eyebrow, no
   frame around the grid. The tile is transparent and the structure is carried
   entirely by the hairlines between cells, which is why the ground must be
   the SAME green as the page: a tile with its own fill reads as a table.

   Three ambient layers, all of them barely there on purpose:
     cfGlassBreathe  a ~1% ivory breathe on the tile itself
     ::before        a sheen travelling along the top hairline
     ::after         a blurred radial glow drifting behind the type
--------------------------------------------------------------------------- */
/* ======================================================================
   THE TWELVE DOORS FILL EXACTLY ONE SCREEN.

   THE BUG THIS FIXES, because it was live and it was expensive:
   site-lattice.css locks `main > section[data-hero]` to
   height/max-height:calc(100svh - header) with overflow:hidden. That rule
   was written for the NINE-door lattice of [data-hero-grid] > [data-tile],
   and its companion rules - the ones that shrink each tile to a third of
   the box - are all keyed to those two names. Home was later rebuilt as
   [data-house-grid] > [data-house-door], which kept the CLIPPING half of
   the bargain and lost the FITTING half: the section stayed 930px tall
   while the grid inside grew to 2045px at twelve doors of `min-height:34vh`.

   The section centres its overflow, so it clipped at BOTH ends. Measured at
   851px: the top row lost its icons and names, and Modelboard, Partner
   Board, FCMAG and Contact were cut off entirely - not merely below the
   fold but unreachable, because overflow:hidden means no scroll ever gets
   there. Four doors, one of them the board that earns the money.

   Rows are now explicit and fractional, so twelve doors divide the box
   instead of overflowing it: 4x3 on a desk, 3x4 from tablet down. Any
   future door count needs its row count changed HERE, or the clipping
   comes straight back.
   ====================================================================== */
[data-house-grid] {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  /* THIRTEEN DOORS INTO A FOUR-COLUMN GRID.
     Thirteen is prime, so it cannot tile: twelve fill three rows and the
     thirteenth takes a shorter full-width band underneath. The band is
     ~.55 of a row so it reads as a footer to the lattice rather than a
     stunted fourth row. Twelve divides by BOTH 4 and 3, which is what lets
     the same trick work unchanged when the columns drop to three. */
  grid-template-rows: repeat(3, minmax(0, 1fr)) minmax(0, .55fr);
  grid-auto-rows: minmax(0, 1fr);
  width: 100%;
  /* The grid is a flex child of the fixed-height hero: it must be allowed
     both to grow into the box and to shrink inside it. min-height:0 is what
     lets a grid shrink below its content at all. */
  flex: 1 1 auto;
  min-height: 0;
  border-top: 1px solid rgba(246, 240, 228, .12);
  border-left: 1px solid rgba(246, 240, 228, .12);
}
@media (max-width: 899px) {
  [data-house-grid] {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: repeat(4, minmax(0, 1fr)) minmax(0, .5fr);
  }
}

/* THE WIDE BAND IS MARKED, NOT INFERRED.
   data-wide on the door itself, never :last-child - site-gate.js can
   display:none a door for a signed-in role, and a structural pseudo-class
   would then hand the full-width band to whichever door happened to fall
   last. Silently, and only for gated visitors, which is the worst kind of
   layout bug to find. */
[data-house-grid] [data-house-door][data-wide] {
  grid-column: 1 / -1;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: clamp(10px, 1.4vw, 20px);
}
[data-house-door][data-wide] .door-name { font-size: clamp(19px, 1.7vw, 27px); }
[data-house-door][data-wide] .door-note { max-width: 46ch; }

[data-house-grid] [data-house-door] {
  position: relative;
  overflow: hidden;
  /* NOT 34vh. Twelve of those is 136vh of grid inside a 100svh box that
     clips - see the block above. The row track sizes the door now. */
  min-height: 0;
  padding: clamp(12px, 1.6vw, 26px) clamp(10px, 1.2vw, 20px);
  background: transparent;
  border-right: 1px solid rgba(246, 240, 228, .12);
  border-bottom: 1px solid rgba(246, 240, 228, .12);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  text-align: center;
  text-decoration: none;
  animation: cfDoorIn .62s var(--fc-ease-standard) both,
             cfGlassBreathe 14s ease-in-out infinite;
  transition: background-color .28s var(--fc-ease-standard),
              transform .28s var(--fc-ease-standard);
}
[data-house-grid] [data-house-door]:hover { background: rgba(246, 240, 228, .06); transform: translateY(-3px); }
[data-house-grid] [data-house-door]:active { transform: translateY(0) scale(.995); }

[data-house-door]::before {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 1px;
  background: linear-gradient(90deg, rgba(246,240,228,0) 20%, rgba(246,240,228,.55) 50%, rgba(246,240,228,0) 80%);
  background-size: 220% 100%;
  animation: cfSheen 8s linear infinite;
  pointer-events: none;
}
[data-house-door]::after {
  content: "";
  position: absolute;
  left: -25%; top: -70%;
  width: 75%; height: 240%;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(246,240,228,.045), rgba(246,240,228,0) 72%);
  filter: blur(26px);
  animation: cfLiquid 19s ease-in-out infinite;
  pointer-events: none;
}

[data-house-door] .door-icon { width: 24px; height: 24px; flex: none; color: var(--fc-ivory); }
[data-house-door] .door-name {
  font: 300 clamp(24px, 2.3vw, 40px)/1.12 var(--font-display);
  letter-spacing: -.005em;
  color: var(--fc-ivory);
  max-width: 100%;
  overflow-wrap: anywhere;
}
[data-house-door] .door-note {
  font: 300 clamp(12px, 1.02vw, 15px)/1.55 var(--font-body);
  color: rgba(246, 240, 228, .6);
  max-width: 30ch;
}

/* ---- THE PHONE IS A HOME SCREEN, NOT A LIST ----------------------------
   Three across, four down, every door reachable without a scroll - which is
   what an app's home screen is, and the thing a website almost never gives
   you. The note goes: at 130px of column there is no honest way to set a
   sentence, and a truncated one is worse than none. The name has to carry
   the door on its own, which is a fair test of the name.

   The 44px minimum is Apple's own hit target and the reason the icon and
   name are centred in a cell rather than pinned to its top. */
@media (max-width: 599px) {
  [data-house-grid] [data-house-door] {
    padding: 10px 6px;
    gap: 9px;
    min-height: 44px;
    /* The lift-on-hover is a mouse idiom. A finger gets a press instead. */
    -webkit-tap-highlight-color: rgba(240, 224, 196, .12);
  }
  [data-house-grid] [data-house-door]:hover { background: transparent; transform: none; }
  [data-house-grid] [data-house-door]:active { background: rgba(246, 240, 228, .1); transform: scale(.96); }
  [data-house-door] .door-icon { width: 27px; height: 27px; }
  [data-house-door] .door-name {
    font: 300 13px/1.22 var(--font-display);
    letter-spacing: .004em;
    overflow-wrap: normal;
    hyphens: none;
  }
  [data-house-door] .door-note { display: none; }
}

/* ======================================================================
   THE FOYER. THREE DOORS, ONE SCREEN.

   Home.dc.html now opens on three doors - The House, Book, Join - and the
   grid carries data-foyer to say so. Everything above still applies: the
   hairlines, cfDoorIn, cfGlassBreathe, the sheen, the liquid, the hover and
   the press. Only the track template changes, so the three doors divide the
   same fixed-height hero box the twelve used to, and the clipping bug that
   block documents cannot come back through a new element name.

   THREE ACROSS ON A DESK, THREE DOWN ON A PHONE. On the phone each door is a
   third of the screen, which is enough room for the name AND the line under
   it - so the phone rule that hides .door-note at thirteen doors is undone
   here. At three, the sentence fits; hiding it would leave a door with a
   name and no invitation.

   NO ICONS. The name is the door. .door-kind is the one-word eyebrow above
   it - website / three clicks / supply - set in the same 10.5px .2em
   uppercase the page uses for its own eyebrow, not a new token.
   ====================================================================== */
[data-house-grid][data-foyer] {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  grid-template-rows: minmax(0, 1fr);
}
@media (max-width: 899px) {
  [data-house-grid][data-foyer] {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: minmax(0, 1fr);
  }
}
/* PORTRAIT ONLY. The hero is locked to 100svh and clips, so three stacked
   rows only fit when the screen is taller than it is wide. A phone turned
   sideways (667x375) would give each row ~95px for ~110px of content and
   lose the eyebrow and the line under the name - so in landscape the doors
   stay three across, where 222px columns set the name comfortably. */
@media (max-width: 599px) and (orientation: portrait) {
  [data-house-grid][data-foyer] {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: repeat(3, minmax(0, 1fr));
  }
}

[data-house-grid][data-foyer] [data-house-door] {
  gap: clamp(10px, 1.4vw, 18px);
  padding: clamp(18px, 2.4vw, 40px) clamp(14px, 2vw, 32px);
}
[data-house-grid][data-foyer] .door-kind {
  font: 600 10.5px/1 var(--font-body);
  letter-spacing: .2em;
  text-transform: uppercase;
  color: rgba(246, 240, 228, .5);
}
[data-house-grid][data-foyer] .door-name {
  font: 300 clamp(34px, 4.2vw, 64px)/1.05 var(--font-display);
  letter-spacing: -.01em;
  overflow-wrap: normal;
}
/* The line under the name is the invitation - Enter, Book an evening, Join
   the house - so it is set as the site sets an action, not as a caption:
   small caps on a hairline, the same treatment as "Ask the desk" on the
   board. */
[data-house-grid][data-foyer] .door-note {
  font: 600 10.5px/1 var(--font-body);
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fc-ivory);
  border-bottom: 1px solid rgba(246, 240, 228, .4);
  padding-bottom: 5px;
  max-width: none;
}
@media (max-width: 599px) {
  [data-house-grid][data-foyer] [data-house-door] {
    gap: 10px;
    padding: 14px 16px;
  }
  [data-house-grid][data-foyer] .door-name {
    font: 300 clamp(30px, 9vw, 42px)/1.05 var(--font-display);
    letter-spacing: -.01em;
  }
  /* Undoes the thirteen-door phone rule above: at three there is room. */
  [data-house-grid][data-foyer] .door-note { display: inline-block; }
}

/* The role gate that used to live here is retired - one home page, thirteen
   doors, the same for everyone. site-gate.js explains why and clears the
   stored answer out of returning visitors' browsers. Nothing sets
   data-cf-role any more, so these rules could never fire again. */

/* The footer collapses its five columns before the brand column gets squeezed. */
@media (max-width: 1099px) {
  fc-footer footer > .fc-container > div:first-child { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}
@media (max-width: 599px) {
  fc-footer footer > .fc-container > div:first-child { grid-template-columns: 1fr !important; }
}

/* The header lockup on a phone.
   site-lattice.css used to swap the wide image lockup for a small mark below
   760px; the lockup is now type, so the equivalent is to drop the wordmark and
   keep the bracketed FC. Those old [data-mark] rules simply match nothing now. */
@media (max-width: 760px) {
  header [data-wordmark] { display: none !important; }
}

/* ---------------------------------------------------------------------------
   THE INTERIOR HEADER — a floating glass pill (README 5.0 / the full-site
   prototypes). Home and Threshold keep the flat bar; every interior page uses
   this. The nav lives behind the menu button and opens on a grid-rows
   transition, so it animates to its real height with no measurement.
--------------------------------------------------------------------------- */
fc-header { display: block; position: relative; z-index: 20; }

/* The roster CTA in the pill. Quiet by default - it sits beside the lockup on
   every interior page, and a loud button repeated 25 times stops being a
   button and becomes wallpaper. It fills on hover, which is where the
   emphasis belongs.
   The label shortens rather than wraps: "Join the roster" needs ~120px it
   does not have on a 375px phone, and a wrapped CTA makes the pill two rows
   tall on every page at once. */
fc-header [data-pill-join] {
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 38px; padding: 0 16px; border-radius: 999px;
  border: 1px solid rgba(240, 224, 196, .38);
  background: transparent; color: var(--cf-ivory-100, #f6f0e4);
  font: 600 10.5px/1 var(--font-body); letter-spacing: .16em; text-transform: uppercase;
  text-decoration: none; white-space: nowrap; border-bottom: 0;
  transition: background-color .28s var(--fc-ease-standard), border-color .28s var(--fc-ease-standard), color .28s var(--fc-ease-standard);
}
fc-header [data-pill-join]:hover {
  background: var(--cf-ivory-100, #f6f0e4); border-color: var(--cf-ivory-100, #f6f0e4); color: #02150E;
}
fc-header [data-pill-join] [data-short] { display: none; }
@media (max-width: 560px) {
  fc-header [data-pill-join] { padding: 0 13px; letter-spacing: .12em; }
  fc-header [data-pill-join] [data-long]  { display: none; }
  fc-header [data-pill-join] [data-short] { display: inline; }
}

fc-header [data-pill] {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  /* Full width with the ends pushed apart — the lockup sits on the far left
     and the action on the far right, with the bar spanning the container.
     Hugging its content made it a short tab floating at the left, which is
     what it looked like before. */
  justify-content: space-between;
  width: 100%;
  gap: 20px;
  padding: 10px 10px 10px 22px;
  border-radius: 999px;
  border: 1px solid rgba(246, 240, 228, .16);
  background: rgba(246, 240, 228, .06);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .22);
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  fc-header [data-pill] { background: rgba(1, 26, 17, .92); }
}
fc-header [data-pill]::before {
  content: "";
  position: absolute; left: 0; right: 0; top: 0; height: 1px;
  background: linear-gradient(90deg, rgba(246,240,228,0) 20%, rgba(246,240,228,.5) 50%, rgba(246,240,228,0) 80%);
  background-size: 220% 100%;
  animation: cfSheen 9s linear infinite;
  pointer-events: none;
}

fc-header [data-menu-btn] {
  width: 38px; height: 38px; flex: none;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  border-radius: 999px;
  border: 1px solid rgba(246, 240, 228, .22);
  background: transparent;
  cursor: pointer;
  transition: background-color 200ms var(--fc-ease-standard);
}
fc-header [data-menu-btn]:hover { background: rgba(246, 240, 228, .1); }
fc-header [data-bar] {
  display: block; width: 15px; height: 1px; background: var(--fc-ivory);
  transition: transform 240ms var(--fc-ease-standard), opacity 160ms linear;
}
/* Open: the outer bars cross, the middle one goes. */
fc-header[data-open] [data-bar]:nth-child(1) { transform: translateY(5px) rotate(45deg); }
fc-header[data-open] [data-bar]:nth-child(2) { opacity: 0; }
fc-header[data-open] [data-bar]:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }

/* The menu FLOATS rather than sitting in flow. A grid-rows reveal was giving
   the row 18px while the links inside were 46px each — the wrapped flex line
   box and the animating row were fighting, and the panel spilled. A dropdown
   is an overlay, so it is positioned as one. */
fc-header .fc-container { position: relative; }

fc-header [data-menu] {
  position: absolute;
  top: 100%;
  right: 24px;
  z-index: 30;
  margin-top: 8px;
  max-width: min(560px, calc(100% - 48px));
  border-radius: 22px;
  border: 1px solid rgba(246, 240, 228, .16);
  background: rgba(2, 40, 27, .92);
  box-shadow: 0 26px 60px rgba(0, 0, 0, .4);
  backdrop-filter: blur(22px) saturate(160%);
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
  transition: opacity 220ms var(--fc-ease-standard), transform 220ms var(--fc-ease-standard);
}
fc-header[data-open] [data-menu] { opacity: 1; transform: none; pointer-events: auto; }

fc-header [data-menu] > div { display: flex; flex-wrap: wrap; gap: 2px; padding: 8px; }
fc-header [data-menu] a { text-decoration: none; transition: background-color 200ms var(--fc-ease-standard); }
fc-header [data-menu] a:hover { background: rgba(246, 240, 228, .12); }

@media (min-width: 900px) { fc-header [data-menu] { right: 40px; } }

@media (max-width: 560px) {
  fc-header [data-wordmark] { display: none; }
  fc-header [data-pill] { padding-left: 14px; }
}

/* ---------------------------------------------------------------------------
   THE HERO PLATE

   No photography ships with this design and none is licensed yet, so a hero
   built around an image opened as a flat green void with the copy stranded
   beneath it. This is the stand-in: an ORIGINAL plate, not a picture — three
   offset radial pools in the green ramp, a soft horizon, a fine grain and a
   vignette. It reads as depth and atmosphere rather than as a missing asset,
   and it carries no licence.

   When real photography arrives, drop an <img> in as the first child of
   [data-hero-plate] and it covers this; the gradient keeps working as the
   backing while the picture loads.
--------------------------------------------------------------------------- */
[data-hero-plate] {
  background:
    radial-gradient(60% 52% at 18% 22%, rgba(44, 151, 105, .30), rgba(1, 26, 17, 0) 68%),
    radial-gradient(52% 46% at 82% 12%, rgba(19, 125, 82, .26), rgba(1, 26, 17, 0) 70%),
    radial-gradient(80% 60% at 60% 96%, rgba(1, 18, 12, .95), rgba(1, 26, 17, 0) 72%),
    linear-gradient(178deg, #06301F 0%, #04231733 42%, #011a11 100%);
}
/* Grain, so the gradient never bands on a wide screen. Inline SVG turbulence:
   no request, and no viewBox to be mangled (the site's renderer camel-cases
   attribute names inside data: URIs — see the note in site-gate.js). */
[data-hero-plate]::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: .5;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)' opacity='.05'/%3E%3C/svg%3E");
}
/* A slow drift, so the plate is not a static wall. One layer, 34s, and it
   stops entirely for reduced motion. */
[data-hero-plate]::after {
  content: "";
  position: absolute;
  left: -20%; top: -30%;
  width: 70%; height: 160%;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(147, 205, 177, .10), rgba(147, 205, 177, 0) 70%);
  filter: blur(40px);
  animation: cfLiquid 34s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) { [data-hero-plate]::after { animation: none; } }

/* A photograph inside the plate sits above the gradient but below the scrim,
   so the gradient backs it while it loads and the type stays readable at any
   crop. Graded down and cooled toward the house green — a plate must never
   arrive as a bright rectangle in a dark room. */
[data-hero-plate] > img { z-index: 0; }
[data-hero-plate]::before, [data-hero-plate]::after { z-index: 1; }

/* Sign in sits at the end of the menu, divided from the doors: it is an
   action, not a room. */
fc-header [data-menu-signin] {
  padding: 12px 16px;
  border-radius: 999px;
  color: var(--fc-accent);
  white-space: nowrap;
  margin-left: auto;
}

/* THE CROP AT NARROW WIDTHS.
   The hero frame is 2.58:1 and the hero box is portrait on a phone, so cover
   shows barely a quarter of the picture. Centred, that quarter landed on the
   dark gap between the two figures and the hero read as an empty green panel
   — the image was loading and painting correctly the whole time.
   Pulled right, onto the subject, and the box is shortened so less of the
   frame is thrown away. */
@media (max-width: 900px) {
  [data-hero-plate] > img { object-position: 64% 44%; }
  [data-hero] { min-height: 62vh !important; }
}
@media (max-width: 600px) {
  [data-hero-plate] > img { object-position: 68% 44%; }
  [data-hero] { min-height: 56vh !important; }
}

/* ===========================================================================
   LIQUID GLASS — the material for glass controls
   (collapsible headers, secondary buttons, pills, the menu)

   Four layers make glass read as glass rather than as a tinted box:
     1. backdrop-filter    the ground behind is blurred AND saturated, so
                           colour bleeds through instead of being greyed
     2. a top specular     inset highlight along the upper edge — the single
                           most important cue; without it you have a panel
     3. a rim light        1px border lifted at the top, darker at the base
     4. depth              an outer shadow so it floats rather than sits

   NOT applied to .fc-btn--primary. The house keeps one solid ivory CTA, and
   making it glass would quieten the one control that must never be quiet.

   Radii are left as each element already has them — the identity is
   hard-edged (2px controls) and only glass surfaces round off. The material
   is the effect here, not the pill shape.
=========================================================================== */

.fc-btn--secondary,
[data-house-open-all],
button[aria-controls^="house-panel"],
.fc-pill {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background:
    linear-gradient(160deg, rgba(246,240,228,.14), rgba(246,240,228,.04) 58%, rgba(246,240,228,.10));
  border: 1px solid rgba(246, 240, 228, .22);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .45),
    inset 0 -10px 22px rgba(1, 26, 17, .34),
    0 10px 28px rgba(0, 0, 0, .26);
  backdrop-filter: blur(18px) saturate(180%);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  transition:
    background-color .38s var(--fc-ease-standard),
    box-shadow .38s var(--fc-ease-standard),
    border-color .38s var(--fc-ease-standard),
    transform .28s var(--fc-ease-standard);
}

/* The specular sweep. Parked off to the left and pulled across on hover —
   the light moving is what makes the surface read as liquid rather than
   frosted. */
.fc-btn--secondary::after,
[data-house-open-all]::after,
button[aria-controls^="house-panel"]::after,
.fc-pill::after {
  content: "";
  position: absolute;
  top: 0; bottom: 0;
  left: -60%;
  width: 45%;
  z-index: -1;
  pointer-events: none;
  background: linear-gradient(100deg,
    rgba(255,255,255,0) 0%,
    rgba(255,255,255,.16) 42%,
    rgba(255,255,255,.34) 50%,
    rgba(255,255,255,.16) 58%,
    rgba(255,255,255,0) 100%);
  filter: blur(6px);
  transform: skewX(-14deg);
  transition: left .62s var(--fc-ease-standard);
}
.fc-btn--secondary:hover::after,
[data-house-open-all]:hover::after,
button[aria-controls^="house-panel"]:hover::after,
.fc-pill:hover::after { left: 115%; }

.fc-btn--secondary:hover,
[data-house-open-all]:hover,
button[aria-controls^="house-panel"]:hover {
  background:
    linear-gradient(160deg, rgba(246,240,228,.22), rgba(246,240,228,.08) 58%, rgba(246,240,228,.16));
  border-color: rgba(246, 240, 228, .38);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .62),
    inset 0 -10px 22px rgba(1, 26, 17, .30),
    0 16px 38px rgba(0, 0, 0, .32);
}
.fc-btn--secondary:active,
[data-house-open-all]:active,
button[aria-controls^="house-panel"]:active { transform: translateY(1px) scale(.995); }

/* Where the browser cannot blur, glass would become a pale rectangle over the
   photograph — fall back to near-solid ground instead. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .fc-btn--secondary,
  [data-house-open-all],
  button[aria-controls^="house-panel"],
  .fc-pill { background: rgba(2, 40, 27, .92); }
}

@media (prefers-reduced-motion: reduce) {
  .fc-btn--secondary::after,
  [data-house-open-all]::after,
  button[aria-controls^="house-panel"]::after,
  .fc-pill::after { display: none; }
}

/* ---------------------------------------------------------------------------
   THE HOUSE PANELS — panoramic, two across

   Five stacked full-width bars made the page a long scroll of near-identical
   rows. Two columns halves the height and lets each panel be read as a card
   rather than a strip, and the section runs wider than the 1200px text
   container because these are structure, not prose — the house look is
   panoramic, and measure only needs protecting where there are sentences.

   The fifth panel spans both columns so the grid closes on a full-width row
   instead of leaving a hole.
--------------------------------------------------------------------------- */
/* The DS caps .cf-container at 1200px and this page never linked
   site-responsive.css, where the rest of the site lifts that cap. Lifted here
   instead, rather than pulling in a stylesheet written for the old pages. */
[data-house-panels] > .cf-container,
[data-house-panels] > div {
  max-width: none;
}
[data-panel-grid] {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  align-items: start;
}
[data-panel-grid] > *:last-child:nth-child(odd) { grid-column: 1 / -1; }

@media (max-width: 1024px) {
  [data-panel-grid] { grid-template-columns: 1fr; }
  [data-panel-grid] > *:last-child:nth-child(odd) { grid-column: auto; }
}

/* --- the menu panel: a four-column grid ----------------------------------
   Nine doors as a wrapped flex row came out ragged, with the rows breaking
   at different points. A fixed four-column grid reads as a directory: four,
   four, then Contact on its own. Below 900px it steps down to two.
--------------------------------------------------------------------------- */
fc-header [data-menu] > div {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 4px 28px;
  padding: 22px 26px;
}
fc-header [data-menu] a {
  font: 300 15px/1 var(--font-body);
  padding: 12px 0;
  border-radius: 0;
  white-space: nowrap;
  transition: color 200ms var(--fc-ease-standard);
}
fc-header [data-menu] a:hover { background: transparent; color: var(--fc-ivory); }
fc-header [data-menu] { max-width: min(920px, calc(100% - 48px)); }
fc-header [data-menu-signin] { margin-left: 0; }

@media (max-width: 900px) {
  fc-header [data-menu] > div { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- one frost, everywhere -----------------------------------------------
   The menu panel and the collapsible panels were frosted differently — the
   menu near-opaque and heavily blurred, the panels thin and translucent, so
   the same material read as two. This is the menu's frost, which is the one
   that holds its shape over a photograph, applied to both. */
fc-header [data-menu],
[data-panel-grid] > * {
  background: rgba(2, 40, 27, .92) !important;
  border: 1px solid rgba(246, 240, 228, .16) !important;
  backdrop-filter: blur(22px) saturate(160%) !important;
  -webkit-backdrop-filter: blur(22px) saturate(160%) !important;
}
