/* ---- typefaces --------------------------------------------------------
   Gardein is served by Adobe Fonts (web project "junastar", kit kgm2geu),
   loaded by the <link> in each page's <head> — Adobe does not permit
   self-hosting, so there is no @font-face for it here and no file in /fonts/.
   The kit is set to All Characters and font-display: block.

   Lunchtype is SIL OFL and stays self-hosted in /fonts/.
   ---------------------------------------------------------------------- */
@font-face{font-family:"Lunchtype";font-weight:400;font-style:normal;font-display:block;
  src:url("/fonts/lunchtype-regular.woff2") format("woff2")}
@font-face{font-family:"Lunchtype";font-weight:400;font-style:italic;font-display:block;
  src:url("/fonts/lunchtype-italic.woff2") format("woff2")}

:root{
  /* ==== PALETTE ========================================================
     Three colours. Muted text is ink at 0.6, never a fourth value.
     ==================================================================== */
  --yellow:#F4DB7A;   /* background */
  --ink:#1A1712;      /* Obsidian. All text, borders, button fills */
  --cream:#FFEFD8;    /* hero spotlight only (js/hero.js CONFIG.lamp) */
  --ink-rgb:26,23,18;                     /* channels, so rgba() derives from --ink */
  --ink-muted:rgba(var(--ink-rgb),.6);    /* kickers, status, footer */

  --pad:clamp(20px,5vw,72px); --head-top:clamp(18px,3vh,30px);

  /* ==== TYPE ===========================================================
     Every font-family, size, weight and leading on this site resolves here.
     Nothing below :root hardcodes type.
     ==================================================================== */
  --font-fallback:Georgia,'Times New Roman',serif;
  --font-display:gardein,var(--font-fallback);   /* Adobe Fonts kit kgm2geu */
  --font-body:"Lunchtype",var(--font-fallback);
  --font-card-title:var(--font-display);   /* card + drop titles: Gardein Regular */
  --font-body-features:normal;

  --weight-h1:300;          /* Gardein Light */
  --weight-h2:400;          /* Gardein Regular */
  /* Only Regular and Italic ship for the body face, so this is 400. Raise it
     if a Medium is ever licensed. */
  --weight-body-medium:400;

  /* ---- scale. Everything is viewport-relative except the small fixed sizes,
     which get a mobile step at the breakpoint below. ---- */
  --size-h1:clamp(40px,5vw,72px);
  --size-lede:clamp(40px,5vw,72px);        /* homepage statement — the h1 of the home page */
  --size-body:clamp(20px,1.6vw,24px);
  --size-nav:20px;                         /* footer links */
  --size-card-title:30px;                  /* drop + product titles */
  --size-kicker:20px;                      /* 'wheels up' — sits under the 72px statement */
  --size-status:16px;                      /* 'coming soon' — sits under a 30px card title */
  --size-footer:16px;                      /* 'powered by human intelligence' */
  --size-fine:13px;                        /* copyright */
  --size-h1-page:56px;                     /* text pages — smaller than the homepage 72 */
  --size-menu:clamp(46px,12vw,76px);       /* fullscreen menu overlay */
  --size-btn:clamp(16px,1.3vw,19px);
  --size-mute:16px;
  --size-h2:1.35em;

  --leading-h1:1.1;
  --leading-body:1.5;
  --leading-display:1.1;
  --leading-h2:1.3;
}
*{box-sizing:border-box}
html{font-size:100%}   /* keeps 1rem at the reader's default, not the fluid body size */
html,body{margin:0;background:var(--yellow);color:var(--ink)}
body{font-family:var(--font-body);font-size:var(--size-body);line-height:var(--leading-body);font-feature-settings:var(--font-body-features);-webkit-font-smoothing:antialiased}
a{color:inherit}
::selection{background:var(--ink);color:var(--yellow)}

/* ---- hero: wordmark + one line, one screen ---- */
#hero{position:relative;height:100svh;min-height:520px;overflow:hidden}
#hero canvas{position:absolute;inset:0;width:100%;height:100%;display:block;touch-action:pan-y;user-select:none;-webkit-user-select:none}
/* same right gutter as the burger: the 8px offset cancels this button's own
   horizontal padding, so the text edge lands exactly on --pad */
#mute{position:absolute;right:calc(var(--pad) - 8px);bottom:calc(var(--head-top) - 6px);appearance:none;border:0;background:transparent;
  font-family:var(--font-body);font-weight:400;font-style:normal;font-size:var(--size-mute);color:var(--ink-muted);
  cursor:pointer;padding:6px 8px;transition:color .12s ease}
#mute:hover,#mute:focus-visible{color:var(--ink);outline:none}
@media (max-width:700px){ #hero{min-height:420px} }

/* ---- site header: burger left, (wordmark centre on text pages), join right ---- */
/* padding matches the burger's own -8px offset, so the header row and the
   burger box occupy the same 40px band and everything centres together */
.site-head{position:absolute;top:0;left:0;right:0;z-index:20;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;padding:calc(var(--head-top) - 8px) var(--pad) 0}
.page .site-head{position:relative}
/* Fixed and above the overlay, so the same control opens the menu and closes
   it: the three lines converge and rotate into an X. Fixed rather than
   absolute because the overlay covers the viewport, and an absolutely placed
   burger would be scrolled off-screen while the menu is open. */
.burger{position:fixed;top:calc(var(--head-top) - 8px);right:calc(var(--pad) - 7px);z-index:60;appearance:none;background:none;border:0;padding:8px;cursor:pointer;width:40px;height:40px}
/* 3px strokes, not hairlines: the wordmark is heavy extruded type and a 2px
   burger read as a different design system sitting next to it. */
.burger span{position:absolute;left:7px;width:26px;height:3px;background:var(--ink);border-radius:1.5px;
  transition:top .45s var(--menu-ease),transform .45s var(--menu-ease) .08s,opacity .2s ease}
.burger span:nth-child(1){top:calc(50% - 9px)}
.burger span:nth-child(2){top:calc(50% - 1.5px)}
.burger span:nth-child(3){top:calc(50% + 6px)}
html.menu-open .burger span:nth-child(1){top:calc(50% - 1.5px);transform:rotate(45deg)}
html.menu-open .burger span:nth-child(2){opacity:0}
html.menu-open .burger span:nth-child(3){top:calc(50% - 1.5px);transform:rotate(-45deg)}
/* the default focus ring is a blue box that belongs to no part of this site */
.burger:focus-visible{outline:2px solid var(--ink);outline-offset:3px;border-radius:6px}
.site-head .mark{grid-column:2}
.mark{display:block;height:40px;width:auto;color:var(--ink)}
.mark svg{display:block;height:100%;width:auto}

/* ---- menu overlay ----
   Two beats on open: the panel slides down and settles first, then the links
   rise in one after another once it is mostly there. Two beats on close, in
   reverse: the links drop out bottom-up, then the panel lifts away. Every
   number is on the :root tokens below so the whole sequence retunes from one
   place. --menu-open-in is a floor for the links: they wait until the panel
   has had time to land. */
:root{
  --menu-ease:cubic-bezier(.16,1,.3,1);   /* expo out, shared with the reveal */
  --menu-panel-in:.85s;  --menu-panel-out:.9s;
  --menu-link-in:.9s;    --menu-link-out:.5s;
  --menu-open-in:.38s;   --menu-stagger:.12s;
  --menu-close-lag:.32s;                  /* panel waits for the links to go */
  --menu-close-stagger:.06s;              /* links leave bottom-up, one by one */
}
.menu{position:fixed;inset:0;z-index:50;background:var(--yellow);display:flex;align-items:center;justify-content:center;padding:var(--pad);
  opacity:0;visibility:hidden;transform:translateY(-28px);
  transition:opacity var(--menu-panel-out) ease var(--menu-close-lag),
             transform var(--menu-panel-out) var(--menu-ease) var(--menu-close-lag),
             visibility 0s linear calc(var(--menu-panel-out) + var(--menu-close-lag))}
.menu.is-open{opacity:1;visibility:visible;transform:none;
  transition:opacity calc(var(--menu-panel-in) * .7) ease,
             transform var(--menu-panel-in) var(--menu-ease),
             visibility 0s}
.menu[hidden]{display:none}
.menu ul{list-style:none;margin:0;padding:0;text-align:center}
.menu li{margin:5.6px 0;opacity:0;transform:translateY(20px);
  transition:opacity var(--menu-link-out) ease,transform var(--menu-link-out) ease}
.menu.is-open li{opacity:1;transform:none;
  transition:opacity var(--menu-link-in) ease,transform var(--menu-link-in) var(--menu-ease)}
.menu li:nth-child(3){transition-delay:0s}
.menu li:nth-child(2){transition-delay:var(--menu-close-stagger)}
.menu li:nth-child(1){transition-delay:calc(var(--menu-close-stagger) * 2)}
.menu.is-open li:nth-child(1){transition-delay:var(--menu-open-in)}
.menu.is-open li:nth-child(2){transition-delay:calc(var(--menu-open-in) + var(--menu-stagger))}
.menu.is-open li:nth-child(3){transition-delay:calc(var(--menu-open-in) + var(--menu-stagger) * 2)}
.menu.is-open li:nth-child(4){transition-delay:calc(var(--menu-open-in) + var(--menu-stagger) * 3)}
.menu a{font-family:var(--font-display);font-weight:var(--weight-h2);font-size:var(--size-menu);line-height:var(--leading-display);text-decoration:none;letter-spacing:-.01em;display:inline-block;padding:.05em .1em .14em;border-bottom:.1em solid transparent;transition:border-bottom-color .12s ease}
.menu a:hover,.menu a:focus-visible{border-bottom-color:currentColor;outline:none}
html.menu-open{overflow:hidden}
@media (prefers-reduced-motion:reduce){
  .menu,.menu li,.burger span{transition-duration:.01ms!important;transition-delay:0s!important}
  .down{animation:none}
}

/* ---- scroll hint: white circle, ink arrow, floats ---- */
.down{position:absolute;left:50%;bottom:clamp(22px,4vh,40px);width:52px;height:52px;margin-left:-26px;
  border-radius:50%;background:var(--cream);color:var(--ink);display:grid;place-items:center;
  animation:bob 2s ease-in-out infinite;opacity:0;transition:opacity .5s ease}
.down svg{width:22px;height:22px}
/* revealed by hero.js once the wordmark has finished building in */
.down.ready{opacity:1}
.down.gone{opacity:0;pointer-events:none}
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-2px)}}

/* ---- statement, under the fold ---- */
.statement{padding:clamp(80px,15vh,150px) var(--pad) clamp(56px,9vh,100px);text-align:center}
.eyebrow{margin:0 0 .9em;font-size:var(--size-kicker);letter-spacing:.06em;color:var(--ink-muted)}
.lede{margin:0 auto;max-width:22ch;font-family:var(--font-display);font-weight:var(--weight-h1);font-size:var(--size-lede);line-height:var(--leading-display);letter-spacing:-.01em}
.btn{display:inline-block;margin-top:2.2em;padding:.7em 1.9em;border:0;border-radius:999px;
  background:var(--ink);color:var(--yellow);text-decoration:none;text-transform:lowercase;
  font-weight:var(--weight-body-medium);font-size:var(--size-btn);transition:opacity .2s}
.btn:hover,.btn:focus-visible{opacity:.85;outline:none}

/* ---- drops: rounded dashed cards, "coming soon" ---- */
.drops{padding:0 var(--pad) clamp(72px,12vh,130px);max-width:1080px;margin:0 auto;text-align:center}
.drop-cards{list-style:none;margin:0 auto;padding:0;width:100%;max-width:28rem;display:grid;grid-template-columns:1fr;gap:clamp(16px,2.4vw,28px)}
.drop{position:relative;border-radius:24px;padding:clamp(34px,3.6vw,48px) 24px;display:grid;gap:8px;place-items:center;
  background:rgba(var(--ink-rgb),.035);border:0;color:var(--ink)}
/* The frame is an inline SVG rect rather than a CSS border: a CSS dashed border
   distributes its dashes to fit each edge, so the corners never match and the
   pattern shifts as the card resizes. A stroked rect keeps one continuous
   dash rhythm the whole way round. Inset by half the stroke so the outer edge
   sits exactly on the card box. */
.drop-frame{position:absolute;inset:.75px;width:calc(100% - 1.5px);height:calc(100% - 1.5px);
  pointer-events:none;overflow:visible}
.drop-frame rect{width:100%;height:100%;fill:none;rx:24px;
  stroke:var(--ink);stroke-opacity:.5;stroke-width:1.5;stroke-dasharray:10 8;
  vector-effect:non-scaling-stroke}
.drop-no,.product-name{font-family:var(--font-card-title);font-weight:var(--weight-h2);font-size:var(--size-card-title);letter-spacing:-.01em}
/* Gardein's 1 is the same tapered stroke as its lowercase l, so "drop 01"
   reads as "drop oi". No OpenType feature changes it — ss01-ss07, onum, lnum,
   salt, tnum, pnum and zero all render identically (tested against the live
   Adobe kit). Lunchtype's 1 has a flag and its l does not, so the numerals
   are set in the body face at the same size and baseline. */
.drop-no .num,.product-name .num{font-family:var(--font-body);font-weight:400;font-style:normal}
.drop-status{font-size:var(--size-status);letter-spacing:.08em;color:var(--ink-muted)}
/* Hover: the dashes travel clockwise round the frame. One period of the
   10/8 dash pattern is 18px, so a -18px offset loops seamlessly, and a
   negative offset moves the dashes with the path (the rect is drawn from the
   top-left, rightwards, so that reads as clockwise). The animation is
   always attached and only its play-state changes, so leaving the card stops
   the dashes where they are instead of snapping them back. Nothing else
   moves and the card is not a link. */
.drop.soon .drop-frame rect{animation:soon 4s ease-in-out infinite,march var(--drop-march) linear infinite;
  animation-play-state:running,paused}
.drop.soon:hover .drop-frame rect{animation-play-state:running,running}
:root{ --drop-march:.9s; }               /* one 18px dash period per cycle */
@keyframes soon{0%,100%{stroke-opacity:.35}50%{stroke-opacity:.7}}
@keyframes march{to{stroke-dashoffset:-18}}
@media (prefers-reduced-motion:reduce){
  .drop.soon:hover .drop-frame rect{animation-play-state:running,paused}
}
.drop:not(.soon){background:var(--ink);color:var(--yellow)}
.drop:not(.soon) .drop-frame rect{stroke:var(--yellow);stroke-opacity:.5;stroke-dasharray:none}
.drop:not(.soon) .drop-status{color:var(--yellow);opacity:.75}

/* ---- footer: centred ---- */
.foot{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:0;padding:32px var(--pad) 44px;text-align:center;width:100%}
.foot .links{display:flex;gap:25.6px;justify-content:center}
.foot .links a{text-decoration:none;border-bottom:1.5px solid currentColor;padding-bottom:2px;font-size:var(--size-nav)}
.tag{margin:1.5rem 0 0;font-size:var(--size-footer);letter-spacing:.04em;color:var(--ink)}
.small{margin:.5rem 0 0;font-size:var(--size-fine);color:var(--ink-muted)}

/* ---- text pages: centred column, left-aligned text, big quiet title ---- */
.prose{max-width:44rem;margin:0 auto;padding:clamp(72px,14vh,150px) var(--pad) clamp(56px,8vh,96px);text-align:left;font-size:var(--size-body);line-height:var(--leading-body);color:var(--ink)}
.prose h1{font-family:var(--font-display);font-weight:var(--weight-h1);font-size:var(--size-h1-page);line-height:var(--leading-h1);margin:0 0 1.2em;letter-spacing:-.015em;color:var(--ink)}
.prose h2{font-family:var(--font-display);font-weight:var(--weight-h2);font-size:var(--size-h2);line-height:var(--leading-h2);margin:2.2em 0 .6em;color:var(--ink)}
.prose p{margin:0 0 1.5em}
.prose a{border-bottom:1.5px solid currentColor;text-decoration:none}
@media (max-width:700px){
  :root{--size-nav:18px;--size-card-title:26px;--size-h1-page:38px;--size-kicker:17px}
  .prose{padding-top:56px}
}

 /* ---- page reveal ----------------------------------------------------
   Hidden only once JS has confirmed it can run (html.js-reveal, set by an
   inline script in <head> so there is no flash), so with JS off or broken
   every element renders normally. Easing and duration are lifted from the
   menu overlay so the two read as the same system. ---- */
/* Three numbers to turn: distance, duration, and the stagger in js/site.js.
   These are tuned for SCROLL, where the page is already moving — the on-load
   values (8px / .38s) were invisible here because the rise was smaller than
   the scroll and the expo curve finished before the element reached the
   reading zone. */
:root{ --reveal-rise:20px; --reveal-dur:.7s; }
html.js-reveal [data-reveal]{opacity:0;transform:translateY(var(--reveal-rise))}
[data-reveal]{transition:opacity var(--reveal-dur) ease,
                         transform var(--reveal-dur) cubic-bezier(.16,1,.3,1)}
html.js-reveal [data-reveal].is-in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  html.js-reveal [data-reveal]{opacity:1;transform:none;transition:none}
}

/* ---- glove cursor: DOM element that follows the pointer (states: rest · point · press · grab). Native cursor hidden when active. ---- */
html.has-glove, html.has-glove *{cursor:none !important}
#glove{position:fixed;left:0;top:0;width:32px;height:32px;pointer-events:none;z-index:9999;opacity:0;transition:opacity .15s;will-change:transform}
#glove img{position:absolute;left:0;top:0;width:32px;height:32px;display:none}
#glove[data-state="rest"] .g-rest,#glove[data-state="point"] .g-point,#glove[data-state="press"] .g-press,#glove[data-state="grab"] .g-grab{display:block}
@media (pointer:coarse){ #glove{display:none} }
