/* Sweetii Drinks & Bakery, one stylesheet, both pages.
   Extracted from the two inline <style> blocks 2026-09-03. Selectors are page-scoped
   by class, so index-only and menu-only rules coexist here without collision. */

:root{
  --ink:#1C1A17;
  --canvas:#FBFAF7;
  --rule:#E3E0DA;

  /* Raw channels exist for every colour that is ever used inside rgba(). Without them
     a tint hardcodes the channel values and silently stops tracking its own token. */
  --ink-rgb:28,26,23;
  --canvas-rgb:251,250,247;

  /* Brand green, sampled from logo-primary.png. */
  --matcha:#2F4A0B;
  --matcha-rgb:47,74,11;
  --matcha-hi:#436B10;
  --taro:#BCA6DC;

  /* Muted ink. Both values are pinned to a measured contrast floor on --canvas:
     .68 = 5.84:1 (text, needs 4.5), .52 = 3.35:1 (icons, needs 3). Do not lower
     either one, .40 shipped here once and put the Wednesday closure at 2.5:1. */
  --muted:rgba(var(--ink-rgb),.68);
  --muted-icon:rgba(var(--ink-rgb),.52);

  /* Ket Marketing's brand green. 4.88:1 on --canvas. The hover DARKENS: the old
     #00B37A lightened to 2.60:1 and failed. */
  --ket:#007E58;
  --ket-hi:#00553C;

  --pad:30px;
  --gap:20px;
  --section:64px;
  --display:"Gloock",Georgia,"Times New Roman",serif;
  --sans:"Schibsted Grotesk","Helvetica Neue",Arial,sans-serif;
}

/* LIGHT ONLY, DELIBERATELY. There is no prefers-color-scheme block and there should not
   be one until someone decides otherwise: the use scene is a phone, in daylight, choosing
   where to get a drink. Every surface below sets an explicit background, so the page cannot
   inherit a host theme -- it simply stays light. Recorded in PRODUCT.md as a commitment. */
*{box-sizing:border-box}
/* scroll-padding-top must clear the sticky nav or in-page anchors land under it.
   The nav is 93px at desktop but wraps to two rows and 158px at <=820px, so this value
   is per-breakpoint. A single desktop value buried the Visit heading by 48px on mobile. */
html{-webkit-text-size-adjust:100%;scroll-padding-top:110px;accent-color:var(--matcha)}
body{
  margin:0;
  background:var(--canvas);
  color:var(--ink);
  caret-color:var(--matcha);
  font-family:var(--sans);
  font-size:17px;
  line-height:1.45;
  transition:background-color .5s ease;
}
img{max-width:100%;display:block}
a{color:inherit;text-underline-offset:3px}
::selection{background:var(--matcha);color:var(--canvas)}
:focus-visible{outline:2px solid var(--matcha);outline-offset:3px;border-radius:2px}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
/* build.mjs wraps every image that has a .webp sibling in a picture element.
   display:contents keeps that wrapper out of layout so `.parent img` rules still apply. */
.pic{display:contents}

/* ---------- shared ---------- */
.label{
  font-size:13px;font-weight:600;text-transform:uppercase;
  letter-spacing:.09em;line-height:1;
}
.display{
  font-family:var(--display);font-weight:400;
  letter-spacing:-.03em;line-height:.92;
}

/* ---------- nav ---------- */
.nav{
  position:sticky;top:0;z-index:50;
  display:flex;align-items:center;justify-content:space-between;
  gap:var(--gap);
  padding:10px var(--pad);
  background:var(--canvas);
  border-bottom:1px solid var(--rule);
}
.mark{display:block;text-decoration:none}
.mark img{height:72px;width:auto}
.nav-links{display:flex;align-items:center;gap:26px}
.nav-links a{text-decoration:none;display:inline-flex;align-items:center;min-height:44px;padding:4px 0}
.nav-links a:hover,.nav-links a[aria-current]{text-decoration:underline;text-underline-offset:4px}
.btn{
  /* 12px, not 11px: at 11 the computed height is 42px and misses the 44x44 touch target. */
  display:inline-block;padding:12px 22px;border-radius:9999px;
  background:var(--matcha);color:var(--canvas);text-decoration:none;
  font-size:14px;font-weight:600;letter-spacing:.02em;
  transition:background-color .2s ease,color .2s ease;
}
.btn:hover{background:var(--matcha-hi)}
.btn--ghost{background:transparent;color:var(--ink);border:1px solid var(--ink);border-radius:10px}
.btn--ghost:hover{background:var(--ink);color:var(--canvas)}

/* ---------- hero ---------- */
.hero{
  position:relative;
  /* Right margin/radius dropped on purpose -- the card runs full-bleed to the
     viewport edge on that side instead of stopping short, so more of the video
     is visible there instead of being cut off by a box that doesn't need to exist. */
  margin:var(--gap) 0 0 var(--pad);
  border-radius:20px 0 0 20px;overflow:hidden;
  min-height:min(82vh,760px);
  display:flex;align-items:flex-end;
  /* Was a hardcoded #E8E6E0 placeholder gray, never meant to be visible. Extreme
     transform-origin values on .hero-bg (see the tuning below) can pull the scaled
     video box off one edge of this container, exposing whatever sits behind it --
     matching the real canvas color means that edge blends instead of seaming. */
  background:var(--canvas);
}
/* Feathers all four edges into the matched canvas background instead of ending
   in a hard cut -- real footage has grain and a slight vignette even in a
   color-matched field, so a flat edge still reads as a seam without this.
   Two gradients intersected (not added) is what makes it fade on every side
   at once instead of just left-to-right. */
.hero-bg{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  -webkit-mask-image:
    linear-gradient(to right,transparent 0%,black 6%,black 80%,transparent 100%),
    linear-gradient(to bottom,transparent 0%,black 6%,black 80%,transparent 100%);
  -webkit-mask-composite:source-in;
  mask-image:
    linear-gradient(to right,transparent 0%,black 6%,black 80%,transparent 100%),
    linear-gradient(to bottom,transparent 0%,black 6%,black 80%,transparent 100%);
  mask-composite:intersect;
}
/* Two scrims in one layer: bottom-up for the CTA row, left-to-right so hero-copy
   reads over whatever the footage happens to be doing there, not just the parts
   that were empty background. Guaranteed legibility beats hunting for clean crops. */
.hero::after{
  content:'';position:absolute;inset:0;height:100%;pointer-events:none;
  background:
    linear-gradient(to right,rgba(var(--canvas-rgb),.94) 0%,rgba(var(--canvas-rgb),0) 58%),
    linear-gradient(to top,rgba(var(--canvas-rgb),.92) 0%,rgba(var(--canvas-rgb),0) 62%);
}
.hero-copy{position:relative;z-index:1;padding:38px;max-width:min(880px,88%)}
.hero h1{margin:14px 0 0;font-size:clamp(52px,8.4vw,116px);line-height:1.05}
.hero-sub{margin:18px 0 0;font-size:18px;max-width:44ch;text-wrap:balance}
.hero-cta{margin-top:22px;display:flex;gap:10px;flex-wrap:wrap}

/* Live open/closed pill. Ships hidden and site.js reveals it, a hardcoded
   "Open until 9" used to sit here and lied every Wednesday. If the script never
   runs, no pill is better than a wrong one; the hours table still has the truth. */
.status{display:inline-flex;align-items:center;gap:9px;background:var(--canvas);border-radius:9999px;padding:8px 15px}
.status[hidden]{display:none}
.dot{width:8px;height:8px;border-radius:50%;background:var(--matcha);flex:none}
.status--shut .dot{background:transparent;box-shadow:inset 0 0 0 2px var(--muted)}

/* ---------- band ---------- */
.band{margin-top:var(--section);padding:52px var(--pad)}
.band--matcha{background:var(--matcha);color:var(--canvas)}
.band--taro{background:var(--taro)}
.band-inner{display:grid;grid-template-columns:1.1fr .9fr;gap:40px;align-items:center;max-width:1240px;margin:0 auto}
.band h2{margin:0;font-size:clamp(38px,5.4vw,74px)}
.band p{margin:20px 0 0;max-width:38ch}
.band-slot{aspect-ratio:4/3;border-radius:20px;background:rgba(var(--canvas-rgb),.4);position:relative;overflow:hidden}
.band-slot img{width:100%;height:100%;object-fit:cover}
.band-slot--portrait{aspect-ratio:4/5;max-width:360px;margin-left:auto}
.band--matcha .band-inner{align-items:stretch}
/* The copy column stretches so the cluster can fill it, but the photo must NOT: stretching
   overrode its aspect-ratio:4/5 and rendered a 0.61 box for a 0.80 image, so object-fit:cover
   shaved the sides off. Centring keeps the slot at the photo's own ratio and crops nothing. */
.band--matcha .band-slot{align-self:center}
.matcha-copy{display:flex;flex-direction:column}
/* Scattered cream-top names, as in the original comp.
   History, so nobody re-breaks this: v1 used percentage coordinates picked by eye and
   "Banana Cream" overlapped both neighbours and spilled the box at every desktop width.
   v2 replaced it with flow layout, which fixed collisions and destroyed the scatter.
   v3 used grid, which put two words in the same column so they shared a left edge and
   read as two stacked columns with a hole in the middle.
   This is v4: absolute placement again, but every left/top pair is chosen against measured
   text widths and verified to have a clear axis-aligned gap at 1440 / 1200 / 1024 / 900.
   AABB-clean is stricter than visually-clean, so rotation cannot introduce a collision.
   If you change a font size here, re-measure. The widths are what drive the positions. */
.matcha-cluster{position:relative;flex:1;margin-top:42px;min-height:clamp(260px,26vw,360px)}
/* NOTE: these spans carried inline style="top:..;left:.." from the original comp until
   2026-09-04. Inline styles beat the stylesheet, so every coordinate below was dead and the
   page silently rendered the comp's arrangement. If positions ever stop responding to this
   block again, check the markup for inline styles first. */
.matcha-cluster span{
  position:absolute;font-family:var(--display);line-height:1;letter-spacing:-.02em;
  white-space:nowrap;transform-origin:center;
}
.matcha-cluster span:nth-child(1){left:0%;  top:3%;    font-size:clamp(26px,3.5vw,48px);transform:rotate(-11deg)}
.matcha-cluster span:nth-child(2){left:74%;  top:2%;     font-size:clamp(23px,3.1vw,42px);transform:rotate(4deg)}
.matcha-cluster span:nth-child(3){left:15%;  top:42%;      font-size:clamp(20px,2.7vw,36px);transform:rotate(10deg);border:1px solid var(--canvas);border-radius:9999px;padding:6px 20px}
.matcha-cluster span:nth-child(4){left:46%;  top:48%;     font-size:clamp(19px,2.5vw,34px);transform:rotate(-6deg)}
.matcha-cluster span:nth-child(5){left:0%;  top:79%;     font-size:clamp(24px,3.2vw,44px);transform:rotate(8deg)}
.matcha-cluster span:nth-child(6){left:62%;  top:80%;    font-size:clamp(20px,2.6vw,35px);transform:rotate(-3deg)}
@media (max-width:820px){
  .band--matcha .band-inner{align-items:normal}
  /* No room to scatter below the band's two-column breakpoint. */
  .matcha-cluster{position:static;display:flex;flex-wrap:wrap;gap:12px 20px;min-height:0}
  .matcha-cluster span{position:static;transform:none;white-space:normal}
}

/* ---------- variety scroll ---------- */
/* Was a 860vh scroll-jacked section: page scroll drove the horizontal translate, and the
   whole thing ate 63% of the desktop page (8.6 of 13.6 screens) for ten photographs, while
   the same content was 9% of the mobile page. The elaborate version therefore only ran for
   the SECONDARY audience, since PRODUCT.md's primary user is phone-first. It is now one
   self-contained scroll row at every viewport, user-initiated, with the mobile treatment
   promoted rather than duplicated. The centre-focus effect survives: it keys off this
   track's own scrollLeft instead of the page's vertical scroll. Page: 13.6 -> 5.7 screens. */
.variety-scroll{margin-top:var(--section)}
.variety-head{padding:0 var(--pad);max-width:1040px}
.variety-head h2{margin:0;font-size:clamp(30px,4.6vw,58px)}
.variety-track{
  display:flex;gap:28px;margin-top:32px;padding:26px var(--pad) 22px;
  overflow-x:auto;overscroll-behavior-x:contain;
  /* No scroll-snap. Snap and an infinite wrap fight each other: assigning scrollLeft while
     snap is active makes the browser re-snap mid-momentum, which is what "tweaks out" on a
     fast fling. A free-scrolling gallery does not need it, and the prev/next buttons still
     move exactly one card so alignment is preserved where it matters. */
  cursor:grab;
  /* The scrollbar IS the desktop affordance. A hidden one makes the row undiscoverable
     with a mouse, so it is themed from the palette rather than removed. */
  scrollbar-width:thin;scrollbar-color:var(--matcha) var(--rule);
}
.variety-track::-webkit-scrollbar{height:8px}
.variety-track::-webkit-scrollbar-track{background:var(--rule);border-radius:9999px}
.variety-track::-webkit-scrollbar-thumb{background:var(--matcha);border-radius:9999px}
.variety-track.is-dragging{cursor:grabbing;user-select:none}
.variety-card{
  flex:0 0 min(360px,66vw);aspect-ratio:4/5;border-radius:20px;overflow:hidden;
  background:#EDEBE5;transform-origin:center;
  transition:transform .35s ease,opacity .35s ease;
}
/* Off-centre cards scale DOWN rather than the centre one scaling up: overflow-x:auto forces
   overflow-y to clip, so anything larger than the track's box would be cut off. */
.variety-card img{width:100%;height:100%;object-fit:cover;filter:brightness(1.08) saturate(1.18);pointer-events:none}
.variety-nav{display:flex;gap:10px;padding:16px var(--pad) 0}
.variety-btn{
  width:48px;height:48px;border-radius:9999px;padding:0;
  border:1px solid var(--ink);background:transparent;color:var(--ink);
  display:inline-flex;align-items:center;justify-content:center;cursor:pointer;
  transition:background-color .2s ease,color .2s ease,opacity .2s ease;
}
.variety-btn svg{width:22px;height:22px}
.variety-btn:hover{background:var(--ink);color:var(--canvas)}
.variety-btn[disabled]{opacity:.3;cursor:default}
.variety-btn[disabled]:hover{background:transparent;color:var(--ink)}
@media (prefers-reduced-motion:reduce){
  .variety-card{transform:none!important;opacity:1!important}
}

/* ---------- homepage counter teaser ---------- */
.menu{margin-top:var(--section);padding:0 var(--pad)}
.menu-head{display:flex;justify-content:space-between;align-items:flex-end;gap:var(--gap);flex-wrap:wrap;margin-bottom:26px}
.menu h2{margin:0;font-size:clamp(40px,6vw,84px)}
.menu-note{font-size:14px;max-width:30ch;color:var(--muted)}
.row-name{font-family:var(--display);font-size:clamp(28px,3.6vw,46px);letter-spacing:-.02em;line-height:1}
.row-price{font-size:17px;font-weight:500;white-space:nowrap;font-variant-numeric:tabular-nums}

/* Six category rows. These were <details> accordions until 2026-09-03: the homepage's job
   is appetite and the menu page's is reference, so hiding the flavour names behind a click
   on the selling page was backwards, and menu.html already lists every one of them
   always-visible. Each row is now a link there instead, bigger target than a summary,
   keeps the page-tint signature, and sends people where the detail actually lives. */
.row{
  display:grid;grid-template-columns:1fr auto;align-items:center;gap:16px;
  padding:22px 12px;border-top:1px solid var(--rule);text-decoration:none;
}
.row:last-of-type{border-bottom:1px solid var(--rule)}
/* Slide the name on hover via transform, not padding, padding animates layout every frame. */
.row .row-name{transition:transform .25s ease}
.row:hover .row-name,.row:focus-visible .row-name{transform:translateX(12px)}

/* ---------- about ---------- */
/* The page's only owner-written copy (Sweetii's own Yelp description) and the only place
   the "sit and stay" visitor is spoken to. Sits between the cakes band and Visit on purpose:
   appetite, then atmosphere, then logistics. On --canvas rather than as a third colour band,
   so it reads as a quiet beat between the taro band above and the map below.
   Centred, which is why it is the one section on the page that is not left-aligned -- that
   difference is what marks it as the pause rather than another product block.
   The storefront sign closes it because that is what a visitor looks for on arrival, which
   hands straight off to the address underneath. */
.about{margin-top:var(--section);padding:0 var(--pad);text-align:center}
.about h2{margin:0;font-size:clamp(34px,4.8vw,66px)}
.about p{margin:24px auto 0;font-size:18px;line-height:1.55;max-width:60ch}
/* Capped at 1040px because storefront.webp is 1360px wide and that is the largest source
   that exists. Full-bleed it rendered ~1380px, i.e. 1x on a retina screen and visibly soft
   on the sign's letterforms. 1040 gives 1.31x, and 3.84x on a phone. */
/* Cropped in CSS rather than in the file: the sign sits left of centre in the source, and
   object-position lets that be corrected without destroying pixels. The original wider
   storefront shot no longer exists, so a bad file crop would be unrecoverable. */
.about-shot{margin:48px auto 0;max-width:1040px;border-radius:20px;overflow:hidden;background:#EDEBE5}
.about-shot img{width:100%;height:auto}

/* ---------- visit ---------- */
.visit{margin-top:var(--section);padding:0 var(--pad)}
.visit-inner{display:grid;grid-template-columns:1fr 1fr;gap:40px}
.visit h2{margin:0 0 16px;font-size:clamp(38px,5.4vw,66px)}
.hours{width:100%;border-collapse:collapse}
.hours th,.hours td{text-align:left;padding:10px 0;border-bottom:1px solid var(--rule);font-size:16px;font-weight:400}
.hours td{text-align:right;font-variant-numeric:tabular-nums}
/* The Wednesday closure is the single most common way a visitor gets burned, so the
   closed row is the LOUDEST row in this table, not a greyed-out one. It used to be
   set at rgba(ink,.4), 2.5:1, the least legible text on the page. */
.hours tr.closed th{font-weight:600}
.hours tr.closed td{font-weight:600;color:var(--matcha)}
.addr{margin:0 0 14px;font-size:18px;line-height:1.5}
.visit-cta{display:inline-block;margin-bottom:20px}
.map-slot{aspect-ratio:5/4;border-radius:20px;background:#EDEBE5;position:relative;overflow:hidden}
.map-slot iframe{width:100%;height:100%;border:0;display:block;pointer-events:none}
.map-slot .map-link{position:absolute;inset:0;z-index:1}

/* ---------- menu page ---------- */
.page-head{padding:56px var(--pad) 0;max-width:920px;margin:0 auto}
.page-head h1{margin:0;font-size:clamp(46px,7vw,88px)}
.page-head p{margin:20px 0 0;font-size:18px;max-width:52ch;color:var(--muted)}
.menu-wrap{padding:0 var(--pad);max-width:920px;margin:0 auto}
.menu-cat{margin-top:var(--section)}
.menu-cat-head{border-bottom:1px solid var(--rule);padding-bottom:14px;margin-bottom:8px}
.menu-cat-head h2{font-size:clamp(30px,4.4vw,44px);margin:0}
.menu-group{padding:22px 0;border-bottom:1px solid var(--rule)}
.menu-group:last-child{border-bottom:0}
.menu-group-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px;flex-wrap:wrap}
.menu-group-head h3{font-family:var(--display);font-weight:400;font-size:26px;letter-spacing:-.01em;margin:0}
.menu-group-price{font-size:15px;font-weight:600;color:var(--muted);white-space:nowrap;font-variant-numeric:tabular-nums}
.menu-group-sub{margin:2px 0 0;font-size:13px;color:var(--muted)}
.menu-chips{margin-top:12px;display:flex;flex-wrap:wrap;gap:8px 10px}
.menu-chips span{font-size:14px;padding:6px 14px;border-radius:9999px;border:1px solid var(--rule);white-space:nowrap}
.menu-callout{margin-top:36px;padding:18px 20px;border-radius:14px;background:rgba(var(--matcha-rgb),.06);font-size:14px;color:var(--muted);max-width:70ch}
.menu-callout strong{font-weight:600;color:var(--ink)}

/* ---------- footer / end card ---------- */
/* Graza's actual end card, which Brian sent 2026-09-03: light ground, dashed hairline
   top and bottom, a dashed vertical rule splitting a left statement block from right
   link columns, legal row last. That composition is what is ported here.
   Deliberately NOT ported: Graza's monospace. Mono is their system font; in Sweetii it
   would be a fourth voice next to Gloock, Schibsted and the script logo, and there is no
   code, data or measurement in a footer to earn it. Sweetii's own type, Graza's bones.
   Also not ported: a raster logo. Graza's footer carries no mark, so the wordmark is
   typeset in Gloock. `assets/brand/logo-primary-alpha-web.png` is still on disk if a
   picture is wanted back here. */
.foot{
  margin-top:var(--section);
  padding:0 var(--pad) 30px;
  background:var(--canvas);color:var(--ink);
}
/* Dashes read lighter than a solid hairline of the same value, so these rules are set
   from ink at .30 rather than --rule, which disappears when dashed. */
.foot-inner{
  display:grid;grid-template-columns:1fr 1fr;
  border-top:1px dashed rgba(var(--ink-rgb),.3);
}
.foot-lede{padding:38px 40px 38px 0;display:flex;flex-direction:column;align-items:flex-start}
.foot-mark img{height:clamp(58px,7vw,82px);width:auto}
.foot-addr{margin:20px 0 0;font-size:15px;line-height:1.6}
/* The left block ends on its action, the way Graza's ends on its form. */
.foot-dir{margin-top:auto;padding-top:28px;font-size:15px;font-weight:600;text-decoration:underline}
.foot-dir:hover{text-decoration-thickness:2px}
.foot-cols{
  display:grid;grid-template-columns:repeat(3,1fr);gap:30px;
  border-left:1px dashed rgba(var(--ink-rgb),.3);
  padding:38px 0 38px 40px;
}
.foot-col .label{display:block;margin-bottom:14px}
.foot-col p{margin:0;font-size:15px;line-height:1.7;color:var(--muted)}
.foot-col a{display:block;font-size:15px;line-height:1.7;color:var(--muted);text-decoration:none}
.foot-col a:hover{color:var(--ink);text-decoration:underline}
/* Same inversion as the hours table: the closure is emphasised, never greyed out. */
.foot-shut{color:var(--matcha);font-weight:600}
.foot-base{
  display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px;
  padding-top:18px;
  border-top:1px dashed rgba(var(--ink-rgb),.3);
  font-size:13px;color:var(--muted);
}
.foot-base a{color:var(--ket);font-weight:600;text-decoration:underline}
.foot-base a:hover{color:var(--ket-hi);text-decoration-thickness:2px}

@media (min-width:821px){
  .map-slot{aspect-ratio:auto;height:100%}
  /* object-position has no horizontal slack to work with here, the video's width already
     exactly fills the hero box at this aspect ratio. Scaling up from a left-anchored origin
     manufactures the slack, pushing the centered glass into the right two-thirds so
     hero-copy sits on clear background, with the ::after scrim as a second layer of
     insurance if the footage ever changes and the crop isn't as clean. */
  .hero-bg{transform:scale(1.24);transform-origin:-40% 0%}
}
@media (max-width:820px){
  :root{--pad:18px;--section:48px}
  html{scroll-padding-top:172px}
  .nav{flex-wrap:wrap;row-gap:10px}
  .nav-links{order:3;width:100%;justify-content:space-between;gap:0;border-top:1px solid var(--rule);padding-top:10px}
  .band-inner,.visit-inner{grid-template-columns:1fr}
  .hero{min-height:74vh}
  .hero-copy{padding:22px}
  .hero-bg{object-position:25% 55%}
  .foot-inner{grid-template-columns:1fr;gap:34px}
  /* 15px/1.7 gives a 26px link. Passes WCAG 2.5.8 (24x24) but not the 44x44 bar, and
     this column is six stacked links on the phone the audience actually arrives on. */
  .foot-col a{padding:9px 0}
  .foot-lede{padding:34px 0 0}
  .foot-cols{grid-template-columns:1fr 1fr;border-left:0;padding:0 0 34px;gap:26px}
  .foot-dir{margin-top:0;padding-top:22px}
}
@media (prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important;scroll-behavior:auto!important}
}
