/* ============================================================
   Chef Life Aruba — shared components

   tokens.css holds the brand: colour, type, the reset.
   This holds the parts that repeat across pages — nav, footer,
   section furniture, buttons, image slots, meta rows.

   Every page then carries its own <style> block for whatever is
   genuinely unique to it. No build step, so this is the seam
   between "shared" and "page". Keep it there.

   ------------------------------------------------------------
   HOW THE TWO TEMPERATURES WORK — read this before adding a
   component.

   The restaurant is marine at night, the private chef is shell in
   the afternoon, and every page ends with an "other door" section
   flipped into the opposite ground. So a light section can sit
   inside a dark page AND a dark section can sit inside a light
   page. Both directions have to work.

   That rules out writing `.is-light .thing{ ... }` overrides.
   A descendant selector like that keeps matching inside a nested
   .on-dark section and outranks the base rule, which is how the
   private chef page once rendered dark ink on a dark ground at
   1.12:1.

   Instead: the ground classes redefine a small set of semantic
   variables, and components only ever read those. Nesting then
   resolves itself through ordinary inheritance — the innermost
   ground wins, at any depth, in either direction.

   Components read  --type, --type-2, --accent, --hairline, …
   Components never read --salt, --ink, --gold, --gold-deep.
   ============================================================ */

:root,
.on-dark{
  --ground:      var(--deep);
  --ground-lift: var(--marine);
  --type:        var(--salt);
  --type-2:      var(--sand);
  --accent:      var(--gold);
  --accent-hi:   var(--gold-lift);
  --on-accent:   var(--deep);
  --hairline:    var(--rule);
  --hairline-2:  var(--rule-soft);
  --hatch:       color-mix(in srgb, var(--salt) 5%, transparent);
  --slot-glow:   color-mix(in srgb, var(--marine-lo) 90%, transparent);
  --grain:       .05;
}

.is-light{
  --ground:      var(--shell);
  --ground-lift: var(--shell-hi);
  --type:        var(--ink);
  --type-2:      var(--ink-60);
  --accent:      var(--gold-deep);
  --accent-hi:   var(--ink);
  --on-accent:   var(--shell-hi);
  --hairline:    var(--rule-ink);
  --hairline-2:  var(--rule-ink);
  --hatch:       color-mix(in srgb, var(--ink) 5%, transparent);
  --slot-glow:   color-mix(in srgb, var(--shell-hi) 80%, transparent);
  --grain:       .035;
}

.on-dark,
.is-light{
  background:var(--ground);
  color:var(--type);
}
.dim{ color:var(--type-2) }

/* ---- rhythm --------------------------------------------------
   One vertical scale, used everywhere. Sections that sit next to
   each other should never disagree about how much air they get. */
:root{
  --bay:    clamp(78px, 13vh, 172px);   /* full section        */
  --bay-sm: clamp(54px, 8vh, 108px);    /* half section        */
  --step:   clamp(18px, 2.4vw, 30px);   /* inside a block      */
}

/* ---- shell -------------------------------------------------- */
.wrap{
  width:100%;
  max-width:1560px;
  margin-inline:auto;
  padding-inline:var(--gutter);
}
.wrap-narrow{ max-width:1180px }
.wrap-text{ max-width:820px }

section{ position:relative }

/* The nav is fixed, so an in-page anchor would otherwise land with
   its heading tucked underneath it. */
section[id], div[id]{ scroll-margin-top:104px }

.pad{ padding-block:var(--bay) }
.pad-sm{ padding-block:var(--bay-sm) }
.pad-top{ padding-top:var(--bay) }
.pad-bottom{ padding-bottom:var(--bay) }

/* ---- type ----------------------------------------------------
   Fraunces is a variable font with an optical-size axis, and
   font-variation-settings overrides font-optical-sizing entirely.
   So opsz has to be declared by hand at every tier — leave it out
   and every size renders at the same optical weight, which is
   exactly the flat, generic look the wonk is meant to avoid.

   Big type wants high opsz (thin hairlines, sharp serifs).
   Small type wants low opsz (sturdier, more open).            */
.d0, .d1, .d2, .d3, .d4{
  font-family:var(--display);
  font-weight:400;
  margin:0;
  text-wrap:balance;
}
.d0{
  font-size:clamp(52px, 11.5vw, 190px);
  line-height:.86;
  letter-spacing:-.035em;
  font-variation-settings:"opsz" 144, "SOFT" 20, "WONK" 1;
}
.d1{
  font-size:clamp(42px, 8.6vw, 124px);
  line-height:.92;
  letter-spacing:-.03em;
  font-variation-settings:"opsz" 132, "SOFT" 20, "WONK" 1;
}
.d2{
  font-size:clamp(30px, 5vw, 62px);
  line-height:1.02;
  letter-spacing:-.025em;
  font-variation-settings:"opsz" 84, "SOFT" 20, "WONK" 1;
}
.d3{
  font-size:clamp(23px, 2.5vw, 33px);
  line-height:1.12;
  letter-spacing:-.02em;
  font-variation-settings:"opsz" 48, "SOFT" 20, "WONK" 1;
}
.d4{
  font-size:clamp(19px, 1.5vw, 22px);
  line-height:1.2;
  letter-spacing:-.015em;
  font-variation-settings:"opsz" 30, "SOFT" 20, "WONK" 1;
}

.lead{
  font-size:clamp(17px, 1.32vw, 20px);
  line-height:1.64;
  max-width:58ch;
  margin:0;
}
.lead + .lead{ margin-top:1.05em }
.lead-lg{
  font-size:clamp(19px, 1.75vw, 26px);
  line-height:1.5;
  max-width:44ch;
  letter-spacing:-.01em;
}

/* Eyebrow — mono, tracked out, with a gold tick before it.
   This is the one repeated ornament in the whole system. */
.eyebrow{
  font-family:var(--mono);
  font-size:11px;
  font-weight:400;
  letter-spacing:.24em;
  text-transform:uppercase;
  display:flex;
  align-items:center;
  gap:14px;
  margin:0 0 clamp(20px, 3vw, 34px);
  color:var(--accent);
}
.eyebrow::before{
  content:"";
  width:26px; height:1px;
  background:currentColor;
  flex:none;
  opacity:.75;
}

.mono{
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.16em;
  text-transform:uppercase;
}

/* Every number on the site lines up in its column. */
.num,
.price,
.meta dd,
time{ font-variant-numeric:tabular-nums }

hr.rule{
  border:0; height:1px;
  background:var(--hairline);
  margin:0;
}

/* ---- grain ---------------------------------------------------
   A single still frame of film grain over the big coloured areas.
   It stops the wide flat gradients from banding on cheap panels
   and gives the photography-free pages something to sit on.

   One inline SVG, no request, no animation.                    */
.grain{ position:relative; isolation:isolate }
.grain::after{
  content:"";
  position:absolute;
  inset:0;
  z-index:0;
  pointer-events:none;
  opacity:var(--grain);
  mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size:160px 160px;
}
.grain > *{ position:relative; z-index:1 }

/* ---- buttons ------------------------------------------------ */
.btn{
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:12px;
  font-family:var(--mono);
  font-size:12px;
  letter-spacing:.16em;
  text-transform:uppercase;
  padding:17px 30px;
  border:1px solid var(--accent);
  color:var(--accent);
  background:transparent;
  border-radius:999px;
  cursor:pointer;
  line-height:1;
  text-align:center;
  position:relative;
  overflow:hidden;
  transition:color .4s var(--ease), border-color .4s var(--ease);
}
/* The fill wipes up from the bottom rather than cross-fading —
   cheaper to composite and it reads as deliberate. */
.btn::before{
  content:"";
  position:absolute;
  inset:0;
  z-index:-1;
  background:var(--accent);
  transform:translateY(101%);
  transition:transform .45s var(--ease);
}
.btn:hover{ color:var(--on-accent) }
.btn:hover::before{ transform:translateY(0) }

.btn-solid{ background:var(--accent); color:var(--on-accent) }
.btn-solid::before{ background:var(--accent-hi) }
.btn-solid:hover{ color:var(--on-accent); border-color:var(--accent-hi) }

.btn-quiet{ border-color:var(--hairline); color:var(--type) }
.btn-quiet::before{ background:var(--type) }
.btn-quiet:hover{ color:var(--ground); border-color:var(--type) }

.btn .arrow{ transition:transform .4s var(--ease) }
.btn:hover .arrow{ transform:translateX(5px) }

@media (prefers-reduced-motion: reduce){
  .btn::before{ display:none }
  .btn:hover{ background:var(--accent); color:var(--on-accent) }
  .btn-quiet:hover{ background:var(--type); color:var(--ground) }
}

/* Long/short label pairs, for buttons whose copy doesn't fit small. */
.btn .short{ display:none }
@media (max-width:560px){
  .btn .long{ display:none }
  .btn .short{ display:inline }
}

/* Text link with a rule that draws in on hover. */
.link{
  font-family:var(--mono);
  font-size:12px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--accent);
  display:inline-flex;
  align-items:center;
  gap:10px;
  padding-bottom:5px;
  position:relative;
}
.link::after{
  content:"";
  position:absolute; left:0; bottom:0;
  width:100%; height:1px;
  background:currentColor;
  transform:scaleX(0);
  transform-origin:left;
  transition:transform .45s var(--ease);
}
.link:hover::after{ transform:scaleX(1) }
.link .arrow{ transition:transform .4s var(--ease) }
.link:hover .arrow{ transform:translateX(5px) }

/* ---- nav ----------------------------------------------------
   The nav sits outside the section flow, so it carries its own
   ground class rather than inheriting one.                     */
.nav{
  position:fixed;
  inset:0 0 auto 0;
  z-index:60;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:20px;
  padding:22px var(--gutter);
  transition:background .5s var(--ease), border-color .5s var(--ease), padding .45s var(--ease);
  border-bottom:1px solid transparent;
  /* A ground class on the nav is there to pick the right variables,
     not to paint it — it floats over the hero until you scroll. */
  background:transparent;
}
.nav[data-stuck="yes"]{
  background:color-mix(in srgb, var(--ground) 86%, transparent);
  backdrop-filter:blur(16px) saturate(140%);
  -webkit-backdrop-filter:blur(16px) saturate(140%);
  border-bottom-color:var(--hairline-2);
  padding-block:13px;
}

/* Reading progress, as a hairline on the nav's own bottom edge.
   Width is set by site.js; it is decoration, so it starts at 0
   and simply never moves if the script does not run. */
.nav::after{
  content:"";
  position:absolute;
  left:0; bottom:-1px;
  height:1px;
  width:var(--progress, 0%);
  background:var(--accent);
  opacity:.85;
  transition:width .12s linear;
}
@media (prefers-reduced-motion: reduce){
  .nav::after{ transition:none }
}

.wordmark{
  font-family:var(--display);
  font-variation-settings:"opsz" 36, "SOFT" 20, "WONK" 1;
  font-size:23px;
  font-weight:500;
  letter-spacing:-.03em;
  line-height:1;
  white-space:nowrap;
}
.wordmark .dot{ color:var(--accent) }

.nav-links{
  display:flex;
  align-items:center;
  gap:clamp(14px, 2vw, 32px);
}
.nav-links a{
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.18em;
  text-transform:uppercase;
  opacity:.7;
  transition:opacity .3s var(--ease), color .3s var(--ease);
  white-space:nowrap;
  position:relative;
}
.nav-links a:hover{ opacity:1; color:var(--accent) }
.nav-links a[aria-current="page"]{ opacity:1; color:var(--accent) }
/* The current page gets a tick under it, not just a colour —
   colour alone is not a state indicator. */
.nav-links a[aria-current="page"]::after{
  content:"";
  position:absolute;
  left:0; right:0; bottom:-7px;
  height:1px;
  background:currentColor;
}

.nav .btn{ padding:12px 22px; font-size:11px }

@media (max-width:1000px){
  .nav-links .hide-sm{ display:none }
}
/* At 320px the nav carries a wordmark, a menu button and a call to
   action, and they have to fit. Everything gets tighter rather than
   anything getting dropped — the CTA is the point of the page. */
@media (max-width:560px){
  .nav{ padding-inline:18px; gap:10px }
  .nav-links{ gap:9px }
  .wordmark{ font-size:19px }
  .nav .btn,
  .menu-btn{ padding:10px 13px; font-size:10px; letter-spacing:.08em }
}

/* ---- mobile menu --------------------------------------------
   A disclosure, not a dialog.

   `.menu-panel[hidden]` is not optional: a bare `display:flex`
   here outranks the UA stylesheet's `[hidden]{display:none}` and
   the panel covers every page permanently.                     */
.menu-btn{
  display:none;
  align-items:center;
  gap:9px;
  background:none;
  border:1px solid var(--hairline);
  border-radius:999px;
  color:inherit;
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.16em;
  text-transform:uppercase;
  padding:11px 18px;
  cursor:pointer;
  white-space:nowrap;
}
@media (max-width:1000px){ .menu-btn{ display:inline-flex } }

.menu-panel{
  position:fixed;
  inset:0;
  z-index:55;
  background:var(--ground);
  color:var(--type);
  display:flex;
  flex-direction:column;
  justify-content:center;
  gap:2px;
  padding:110px var(--gutter) 40px;
  overflow-y:auto;
}
.menu-panel[hidden]{ display:none }

.menu-panel a{
  font-family:var(--display);
  font-variation-settings:"opsz" 60, "SOFT" 20, "WONK" 1;
  font-size:clamp(28px, 8vw, 46px);
  line-height:1.24;
  letter-spacing:-.025em;
  border-bottom:1px solid var(--hairline-2);
  padding-block:14px;
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:16px;
}
.menu-panel a:last-of-type{ border-bottom:0 }
.menu-panel a .n{
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.2em;
  color:var(--type-2);
}

.menu-panel .contact{
  margin-top:26px;
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--type-2);
  line-height:2;
  word-break:break-word;
}
.menu-panel .contact a{
  font-family:inherit;
  font-size:inherit;
  letter-spacing:inherit;
  border:0;
  padding:0;
  line-height:inherit;
  display:inline;
}

/* ---- status pip ---------------------------------------------
   The live readout is the one thing on the site that cannot
   degrade into something readable: "SUNSET —:—" doesn't say
   "scripting is off", it says "this restaurant is broken". So it
   is hidden until the clock is actually running. Everything else
   on the page still works without it.                          */
.no-js .readout{ display:none }

.pip{
  display:inline-flex;
  align-items:center;
  gap:9px;
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.18em;
  text-transform:uppercase;
}
.pip::before{
  content:"";
  width:7px; height:7px;
  border-radius:50%;
  background:var(--type-2);
  flex:none;
}
.pip[data-sky-open="yes"]{ color:var(--turquoise) }
.pip[data-sky-open="yes"]::before{
  background:var(--turquoise);
  box-shadow:0 0 0 0 color-mix(in srgb, var(--turquoise) 70%, transparent);
  animation:pulse 2.6s var(--ease) infinite;
}
.pip[data-sky-open="no"]{ color:var(--type-2) }
@keyframes pulse{
  0%{   box-shadow:0 0 0 0 color-mix(in srgb, var(--turquoise) 55%, transparent) }
  70%{  box-shadow:0 0 0 9px color-mix(in srgb, var(--turquoise) 0%, transparent) }
  100%{ box-shadow:0 0 0 0 color-mix(in srgb, var(--turquoise) 0%, transparent) }
}

/* The live instrument. Mono, tabular, on its own rules — it should
   read like a gauge, not a badge. */
.readout{
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  border:1px solid var(--hairline);
  border-radius:3px;
  /* This sits over the sky, which runs from bright cream at golden
     hour to near-black at midnight. Any middling tint mixes with the
     bright horizon into olive — deep navy at 74% over cream lands on
     rgb(60,71,70), which looks like dirt rather than glass. So it
     commits: a near-solid dark panel at every hour, with a hairline
     of light along the top edge so it reads as an instrument rather
     than a sticker. No saturate() — it was amplifying exactly the
     warm cast that made it muddy. */
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--type) 10%, transparent) 0,
      transparent 1.5px),
    color-mix(in srgb, var(--ground) 92%, transparent);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
  align-self:flex-start;
  max-width:100%;
}
.readout > *{
  padding:15px clamp(15px, 2vw, 24px);
  border-right:1px solid var(--hairline-2);
}
.readout > *:last-child{ border-right:0 }
.readout .num{
  font-family:var(--mono);
  font-size:11px;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--type-2);
  display:flex;
  align-items:baseline;
  gap:10px;
  white-space:nowrap;
}
.readout .num b{
  font-weight:400;
  color:var(--type);
  font-size:14px;
  letter-spacing:.06em;
}

/* ---- meta rows ----------------------------------------------
   Label above value, mono label, display value. Used for the
   hours/seating/party-size triplets on both sides.             */
.meta{
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(150px, 1fr));
  gap:clamp(20px, 3vw, 44px);
  border-top:1px solid var(--hairline);
  padding-top:26px;
}
.meta dt{
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--type-2);
  margin-bottom:9px;
}
.meta dd{
  margin:0;
  font-family:var(--display);
  font-variation-settings:"opsz" 28, "SOFT" 20, "WONK" 1;
  font-size:clamp(17px, 1.5vw, 21px);
  line-height:1.24;
  letter-spacing:-.01em;
}

/* ---- image slots --------------------------------------------
   Every frame is a numbered slot from one shoot list. They are
   built to look deliberate while empty — a reserved plate, not a
   broken image.

   To fill one: drop a <picture> in as the first child and delete
   the <figcaption>. The aspect ratio lives on the figure, so the
   layout does not move when the photography lands.            */
.slot{
  position:relative;
  overflow:hidden;
  background:var(--ground-lift);
  border:1px solid var(--hairline);
  display:flex;
  align-items:flex-end;
  isolation:isolate;
}
.slot::before{
  content:"";
  position:absolute; inset:0;
  z-index:-1;
  background:repeating-linear-gradient(
    -45deg,
    transparent 0 13px,
    var(--hatch) 13px 14px
  );
}
.slot::after{
  content:"";
  position:absolute; inset:0;
  z-index:-1;
  background:radial-gradient(120% 90% at 50% 0%, var(--slot-glow), transparent 70%);
}
.slot figcaption{
  font-family:var(--mono);
  font-size:9.5px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--type-2);
  padding:16px 18px;
  line-height:1.5;
  max-width:44ch;
}
.slot img,
.slot picture{
  width:100%; height:100%;
  object-fit:cover;
  display:block;
}
/* A filled slot loses the hatch and the frame — it is a photograph
   now, not a placeholder. */
.slot:has(img){ border-color:transparent; background:var(--ground-lift) }
.slot:has(img)::before{ display:none }

.slot-wide{ aspect-ratio:16/9 }
.slot-tall{ aspect-ratio:3/4 }
.slot-square{ aspect-ratio:1 }
.slot-port{ aspect-ratio:4/5 }
.slot-pano{ aspect-ratio:21/9 }
@media (max-width:640px){
  .slot-tall,
  .slot-pano{ aspect-ratio:4/5 }
}

/* A slot that quietly drifts as you scroll past. The offset is set
   by site.js and defaults to zero, so it is inert without it. */
.slot-drift > .drift{
  transform:translate3d(0, var(--drift, 0px), 0);
  will-change:transform;
}
@media (prefers-reduced-motion: reduce){
  .slot-drift > .drift{ transform:none }
}

/* ---- tags ---------------------------------------------------- */
.tag{
  display:inline-block;
  font-family:var(--mono);
  font-size:9.5px;
  letter-spacing:.16em;
  text-transform:uppercase;
  padding:5px 10px;
  border:1px solid var(--hairline);
  border-radius:999px;
  color:var(--type-2);
  line-height:1;
  white-space:nowrap;
}
.tag-accent{ color:var(--accent); border-color:currentColor }

/* ---- price --------------------------------------------------- */
.price{
  font-family:var(--mono);
  font-size:14px;
  font-weight:400;
  letter-spacing:.02em;
  color:var(--accent);
  white-space:nowrap;
}
.price-tbc{
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--type-2);
  white-space:normal;
}

/* ---- the other door -----------------------------------------
   The one section on every page rendered in the opposite
   temperature. Land on either side, scroll to the bottom, and
   the two-business structure explains itself without a word of
   navigation copy.                                             */
.door{
  display:grid;
  grid-template-columns:1.05fr .95fr;
  align-items:center;
  gap:clamp(32px, 6vw, 96px);
}
@media (max-width:940px){
  .door{ grid-template-columns:1fr; gap:40px }
}

/* ---- split --------------------------------------------------- */
.split{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:clamp(34px, 6vw, 100px);
  align-items:center;
}
.split-top{ align-items:start }
@media (max-width:940px){
  .split{ grid-template-columns:1fr; gap:44px }
}
.split-copy > .lead{ margin-top:var(--step) }
.split-copy > .meta{ margin-top:clamp(34px, 5vw, 54px) }
.split-copy > .btn,
.split-copy > .link{ margin-top:clamp(28px, 4vw, 40px) }

/* ---- page head ----------------------------------------------
   The masthead every inner page opens with. Same shape each time
   so the set reads as one publication.                        */
.masthead{
  padding-block:clamp(136px, 21vh, 220px) var(--bay-sm);
  position:relative;
}
.masthead .d1{ max-width:15ch }
.masthead .lead-lg{ margin-top:clamp(22px, 3vw, 32px) }
.masthead-foot{
  margin-top:clamp(38px, 5vw, 60px);
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  gap:14px 28px;
}

/* ---- next page ----------------------------------------------
   Inner pages hand off to the next one instead of dead-ending.  */
.onward{
  border-top:1px solid var(--hairline);
  display:grid;
  grid-template-columns:1fr 1fr;
}
@media (max-width:760px){ .onward{ grid-template-columns:1fr } }
.onward a{
  padding:clamp(30px, 4.4vw, 56px) 0;
  display:flex;
  flex-direction:column;
  gap:12px;
  transition:opacity .4s var(--ease);
}
.onward a + a{
  border-left:1px solid var(--hairline);
  padding-left:clamp(24px, 4vw, 56px);
}
@media (max-width:760px){
  .onward a + a{ border-left:0; border-top:1px solid var(--hairline); padding-left:0 }
}
.onward .k{
  font-family:var(--mono);
  font-size:10px;
  letter-spacing:.2em;
  text-transform:uppercase;
  color:var(--type-2);
}
.onward .t{
  font-family:var(--display);
  font-variation-settings:"opsz" 44, "SOFT" 20, "WONK" 1;
  font-size:clamp(24px, 3vw, 36px);
  letter-spacing:-.022em;
  line-height:1.1;
  display:flex;
  align-items:baseline;
  gap:14px;
}
.onward a:hover .t{ color:var(--accent) }
.onward .t .arrow{ transition:transform .4s var(--ease) }
.onward a:hover .t .arrow{ transform:translateX(6px) }

/* ---- footer -------------------------------------------------- */
.foot{
  border-top:1px solid var(--hairline);
  padding-block:44px 40px;
  display:flex;
  flex-wrap:wrap;
  align-items:center;
  justify-content:space-between;
  gap:18px 34px;
  font-family:var(--mono);
  font-size:10.5px;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--type-2);
}
.foot a:hover{ color:var(--accent) }
.foot .stamp{ opacity:.7 }

/* ---- utility ------------------------------------------------- */
.skip{
  position:absolute;
  left:-9999px;
  top:0;
  z-index:100;
  background:var(--gold);
  color:var(--deep);
  padding:14px 22px;
  font-family:var(--mono);
  font-size:12px;
  letter-spacing:.14em;
  text-transform:uppercase;
}
.skip:focus{ left:var(--gutter); top:14px }

.vh{
  position:absolute!important;
  width:1px; height:1px;
  margin:-1px; padding:0;
  overflow:hidden;
  clip:rect(0 0 0 0);
  white-space:nowrap;
  border:0;
}

/* ---- reveal --------------------------------------------------
   Content rises as it enters. Children of [data-stagger] get an
   index from site.js and follow each other in.

   Two rules that must not be broken: nothing may end up stuck at
   opacity 0 if the script never runs, and the whole thing is off
   under reduced motion.                                        */
.rise{
  opacity:0;
  transform:translate3d(0, 26px, 0);
  transition:opacity .95s var(--ease), transform .95s var(--ease);
  transition-delay:calc(var(--i, 0) * 85ms);
}
.rise.in{ opacity:1; transform:none }
@media (prefers-reduced-motion: reduce){
  .rise{ opacity:1; transform:none; transition:none }
}

/* ---- print ---------------------------------------------------
   Someone will print the menu. It should come out as a menu.   */
@media print{
  :root, .on-dark, .is-light{
    --ground:#fff; --ground-lift:#fff;
    --type:#000; --type-2:#333;
    --accent:#000; --hairline:#bbb; --hairline-2:#ddd;
    --grain:0;
  }
  html, body{ background:#fff!important; color:#000!important }
  .nav, .menu-panel, .menu-btn, .readout, .skip,
  .onward, .slot, .btn, .grain::after{ display:none!important }
  .rise{ opacity:1!important; transform:none!important }
  a{ text-decoration:none; color:#000 }
  .pad, .pad-sm, .masthead{ padding-block:12px }
  section{ break-inside:avoid }
}
