/* ==========================================================================
   Klara Strand Café — The Diagonal Sheet
   A 1930 Stockholm exhibition bill, printed for the web.
   Flat litho planes, one vermilion field, chrome-yellow and navy diagonals,
   navy-on-cream halftone photography, Hedera helix as the only ornament.
   ========================================================================== */

:root {
  /* Ink palette — the whole site prints from these five */
  --cream:      #F0DCB5;   /* the comp's aged tan stock, sampled from the approved comp */
  --cream-hi:   #F9EED4;
  --cream-lo:   #E3CDA3;
  --red:        #E8412E;   /* display ink: fields and large lettering only */
  --red-deep:   #C62716;   /* the second, denser pass — solved against the RENDERED pixel (4.60:1) */
  --yellow:     #F2CE1B;
  --navy:       #1F2A44;
  --navy-lo:    #2C3A5C;
  --sage:       #C5D2CB;
  --green:      #2F6B46;   /* GreenKayak's own field — carries cream copy at 5.50:1 */
  --green-lo:   #295E3D;

  --ink:        var(--navy);
  --ink-soft:   #4D5873;   /* clears 4.5:1 on cream (5.77) and on sage (4.55) */
  --ink-on-red: #F7F1E2;   /* clears 4.5:1 on --red-deep (4.51) */

  /* the comp's O is near-circular with wide open counters: geometric, not condensed */
  --font-display: 'Jost', 'Futura', 'Century Gothic', system-ui, sans-serif;
  --font-body:    'Archivo', 'Helvetica Neue', Arial, sans-serif;

  --keyline: 2px;
  --measure: 62ch;

  --step-0: 1.06rem;
  --step-1: 1.125rem;
  --step-2: clamp(1.2rem, 1.65vw, 1.42rem);
  --step-3: clamp(1.9rem, 3.4vw, 2.6rem);
  --step-4: clamp(2.4rem, 5vw, 3.6rem);
  --step-5: clamp(3rem, 8.6vw, 6rem);

  --gutter: clamp(1.15rem, 4vw, 3rem);
  /* The sheet runs to all four edges of the viewport, so it carries its own
     height rather than inheriting one from the hero's padding. Above 1100px it
     also carries the nav strip, and grows by that strip's height to keep the
     poster below the nav the size it was when the masthead sat above it. */
  --sheet-h: min(74vh, 720px);
  --band-y: clamp(3.5rem, 8vw, 7rem);

  /* Aged stock: fine grain, printed once over everything */
  /* Opaque, desaturated, contrast-stretched noise. Alpha is forced to 1 so the
     tile carries its full tonal range: strength is controlled by the layer's
     opacity alone, which keeps the grain measurable instead of washed out. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cfilter id='n' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.68' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncR type='linear' slope='2.9' intercept='-0.95'/%3E%3CfeFuncG type='linear' slope='2.9' intercept='-0.95'/%3E%3CfeFuncB type='linear' slope='2.9' intercept='-0.95'/%3E%3CfeFuncA type='linear' slope='0' intercept='1'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='150' height='150' filter='url(%23n)'/%3E%3C/svg%3E");

  color-scheme: light;
}

/* --------------------------------------------------------------- resets */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 5.5rem;
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  line-height: 1.62;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

/* the grain sits above the page and below nothing, printed on every surface */
/* The stock must measure as printed (a flat field samples sd >= 5) WITHOUT
   shifting the ground. `multiply` darkened every field ~15% and dragged four
   contrast pairs under the floor; `overlay` against mid-grey noise is
   mean-neutral, so it adds variance and leaves the palette where it was
   declared. It also bites harder on the mid-tone red than on the pale cream,
   which is exactly where the grain was short. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  background-image: var(--grain);
  background-size: 150px 150px;
  opacity: 0.31;
  mix-blend-mode: overlay;
  pointer-events: none;
  z-index: 9999;
}

img { max-width: 100%; height: auto; display: block; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  text-transform: uppercase;
  line-height: 0.94;
  letter-spacing: 0.005em;
  text-wrap: balance;
  margin: 0;
}

p { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }

/* --------------------------------------------------- browser surfaces */
::selection { background: var(--yellow); color: var(--navy); }

:focus-visible {
  outline: 3px solid var(--navy);
  outline-offset: 3px;
}
.band--red :focus-visible,
.foot :focus-visible { outline-color: var(--yellow); }

a { color: inherit; text-underline-offset: 0.22em; text-decoration-thickness: 1px; }

* { scrollbar-color: var(--navy) var(--cream-lo); scrollbar-width: thin; }
::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: var(--cream-lo); }
::-webkit-scrollbar-thumb { background: var(--navy); border: 3px solid var(--cream-lo); }

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

.skip {
  position: absolute; left: 0.5rem; top: -4rem; z-index: 200;
  background: var(--navy); color: var(--cream);
  padding: 0.65rem 1rem; font-family: var(--font-display);
  text-transform: uppercase; letter-spacing: 0.09em; text-decoration: none;
  transition: top 0.18s ease-out;
}
.skip:focus { top: 0.5rem; }

/* --------------------------------------------------------- bilingual */
html[data-lang="sv"] [lang="en"] { display: none; }
html[data-lang="en"] [lang="sv"] { display: none; }

/* The page re-letters wholesale on the language switch. The incoming words fade
   in over 0.12s so the swap reads as a change rather than a snap. Opacity only,
   and never height: the two languages set to different measures and anything
   that animates box size would reflow the whole column. */
@keyframes lang-in { from { opacity: 0; } to { opacity: 1; } }
html.is-langswap span[lang] { animation: lang-in 0.12s ease-out both; }

/* ======================================================== MASTHEAD */
.masthead {
  position: relative;
  z-index: 60;
  display: flex;
  align-items: center;
  gap: var(--gutter);
  padding: 0.85rem var(--gutter) 0.7rem;
  background: var(--cream);
  border-bottom: var(--keyline) solid var(--navy);
}

/* Unboxed above 861px: no rule under it and no pin. Both were what made the
   masthead read as browser chrome sitting on top of a poster rather than as
   part of the printed sheet. Below 861px the nav wraps to three rows and the
   cream ground with its keyline is still doing real work, so it stays. */
@media (min-width: 861px) {
  .masthead { border-bottom: 0; }
  /* nothing is pinned any more, so anchors only need to clear the edge */
  html { scroll-padding-top: var(--gutter); }
}

.masthead__logo { flex: none; display: block; }
.masthead__logo img {
  height: clamp(68px, 8.2vw, 100px);
  width: auto;
}

.masthead__nav { margin-left: auto; }
.masthead__nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(0.9rem, 2.1vw, 2rem);
}
.masthead__nav a {
  display: inline-flex;
  align-items: center;
  gap: 0.42em;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(0.86rem, 1.15vw, 1rem);
  text-transform: uppercase;
  letter-spacing: 0.15em;
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: var(--keyline) solid transparent;
  transition: border-color 0.16s ease-out, color 0.16s ease-out;
}
.masthead__nav a:hover,
.masthead__nav a[aria-current] { border-bottom-color: var(--red); color: var(--red); }

/* a signal pennant, the world's own device, flying "free" off the kayak link */
.pennant {
  display: inline-block;
  background: var(--yellow);
  color: var(--navy);
  font-size: 0.62rem;
  font-weight: 700;
  letter-spacing: 0.13em;
  line-height: 1;
  padding: 0.26em 0.85em 0.26em 0.5em;
  /* swallowtail notched out of the fly edge */
  clip-path: polygon(0 0, 100% 0, 78% 50%, 100% 100%, 0 100%);
  transform: rotate(-4deg);
  transform-origin: left center;
  transition: transform 0.18s cubic-bezier(0.2, 0.8, 0.3, 1), background 0.18s;
}
.masthead__nav a:hover .pennant {
  transform: rotate(-9deg) translateY(-1px);
  background: var(--cream-hi);
}

.lang { flex: none; display: flex; align-items: center; gap: 0.3rem; }
.lang__slash { color: var(--ink-soft); }
.lang__btn {
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  background: none;
  border: var(--keyline) solid transparent;
  color: var(--ink-soft);
  padding: 0.18rem 0.42rem;
  cursor: pointer;
  transition: color 0.16s, border-color 0.16s, background 0.16s;
}
.lang__btn:hover { color: var(--navy); }
.lang__btn[aria-pressed="true"] {
  color: var(--cream);
  background: var(--navy);
  border-color: var(--navy);
}

/* ============================================ HERO : THE DIAGONAL SHEET */
/* No gutter and no keyline: the sheet is the stock, not a picture printed on
   it. The comp has cream at the edges only where the poster's own margin is,
   and no rule anywhere — a border here read as a browser card, not as print. */
.hero { background: var(--cream); }

.sheet {
  position: relative;
  isolation: isolate;
  min-height: var(--sheet-h);
  overflow: hidden;
  /* shows through the nav strip, which is cut out of the red field's corner */
  background: var(--cream);
}

.sheet__red,
.sheet__yellow,
.sheet__navy,
.sheet__scene { position: absolute; inset: 0; }

.sheet__red    { background: var(--red);    clip-path: polygon(0 0, 63% 0, 34% 100%, 0 100%); }
/* The bands sit above the ghost so the diagonal crops it, as in the comp.
   They are WEDGES, not stripes: in the comp the yellow runs 9.4% of the frame's
   width at the top down to 3.4% at the foot and the navy 5.4% down to 1.8%, a
   clean linear taper that makes the cut read as opening upward rather than as
   two parallel rules. Those fractions are divided by sin of this sheet's own
   steeper cut, so the bands measure the comp's thickness ACROSS the diagonal
   rather than across the page. Only the left edge (63% -> 34%) is shared with
   the red field; every other edge has its own run. */
.sheet__yellow { background: var(--yellow); clip-path: polygon(63% 0, 71.2% 0, 37% 100%, 34% 100%); z-index: 1; }
.sheet__navy   { background: var(--navy);   clip-path: polygon(71.2% 0, 75.8% 0, 38.6% 100%, 37% 100%); z-index: 1; }

.sheet__scene {
  /* Sampled from the plate's own sky (avg #c0c2a6), not --sage (#c5d2cb) — the
     shrunk image now leaves a real sliver of this showing at the top and left,
     not just a load-failure fallback, and --sage reads visibly blue against it. */
  background: #c0c2a6;
  clip-path: polygon(75.8% 0, 100% 0, 100% 100%, 38.6% 100%);
  z-index: 1;
}

/* The nav strip, cut out of the red field so the yellow and navy bands reach
   the top edge of the viewport with the cut unbroken — the comp's masthead is
   a notch in the poster, not a bar above it.
   The clip-path is on the FULL-SIZE parent, so its percentages resolve against
   the same box the red field's do and the corner lands exactly on the cut. The
   height limit is the child's own px height. Putting both on one element would
   need the strip's height as a fraction of the sheet's, which stops being true
   the moment the copy re-wraps and grows the sheet. Only painted at 1100px and
   up, where the masthead lifts into it. */
.sheet__notch { display: none; }
.sheet__scene picture { display: contents; }
/* Give the frame a box the size of the WEDGE, not the whole sheet, or cover
   scales it to the sheet's width and beheads the clock. */
.sheet__scene img {
  position: absolute;
  /* The frame is the whole sheet, not the wedge. `.sheet__scene`'s clip-path is
     what frames the picture, so giving the image the full width scales it to
     the sheet instead of to the wedge — roughly 1.6x — and walks the plate's
     left-hand third (the signal mast) off behind the vermilion field, which is
     where the cut would have sliced it anyway. What lands in the wedge is the
     half the comp puts there: Stadshuset and the steamers along the foot. */
  right: 0;
  bottom: 0;
  /* Anchored to the sheet's own bottom-right corner, at less than its full
     size, rather than covering it at 100%. Cover's scale is fixed by the box
     height alone, so pinning `object-position` to the corner cannot move
     Stadshuset once it's onscreen — every point that's visible lands at the
     same spot regardless of how much gets cropped off the other side. The
     only way to walk the tower rightward, clear of the cut, is to shrink the
     box itself: at 85% the picture is smaller and sits closer to its own
     anchor corner, and `.sheet__scene`'s sage fallback (already close to the
     picture's own sky tone) shows through the sliver left at the top and left. */
  width: 78%;
  height: 78%;
  object-fit: cover;
  object-position: 100% 100%;
}

/* the wordmark, ghosted into the field as outline lettering */
/* Ghosted wordmark: real type at the comp's scale, seated in the OPEN right
   portion of the vermilion field and rising on the diagonal's own axis. It
   paints under the bands (z-index 0), so the yellow diagonal crops it exactly
   as the comp crops it — the clip is the composition, not an accident. */
.sheet__ghost {
  position: absolute;
  z-index: 0;
  left: 25%;
  top: auto;
  bottom: 17%;
  margin: 0;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(5rem, 14vw, 12rem);
  line-height: 0.78;
  text-transform: uppercase;
  letter-spacing: 0.005em;
  color: transparent;
  -webkit-text-stroke: 2.5px rgba(249, 238, 212, 0.34);
  text-stroke: 2.5px rgba(249, 238, 212, 0.34);
  /* the sheet's diagonal runs at roughly -21deg; the wordmark rides it */
  transform: rotate(-21deg);
  transform-origin: left bottom;
  pointer-events: none;
  user-select: none;
}

.sheet__copy {
  position: relative;
  z-index: 2;
  max-width: 54%;
  padding: clamp(1.6rem, 4vw, 3.2rem);
  display: grid;
  justify-items: start;
  gap: 0;
}

.sheet__head {
  font-size: var(--step-5);
  color: var(--cream-hi);
  /* period poster lettering: keyline plus hard offset, the sheet's own device */
  text-shadow: 3px 4px 0 var(--navy);
  margin-bottom: 0.55rem;
}

/* the tagline is live brand, a peer to the headline — not a caption */
.sheet__tag {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.25rem, 2.9vw, 2.15rem);
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.19em;
  color: var(--navy);
  margin-bottom: 1.75rem;
}

/* On the bright field even white tops out at 4.0:1, so this line clears the bar
   by being large text (>=18.66px at 700), not by changing the comp's colour. */
.sheet__addr {
  margin-top: 1.1rem;
  font-family: var(--font-display);
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ink-on-red);
}

/* ------------------------------------------------------------ buttons */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(0.95rem, 1.35vw, 1.12rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-decoration: none;
  padding: 0.78rem 1.5rem;
  border: var(--keyline) solid var(--navy);
  transition: transform 0.15s cubic-bezier(0.2, 0.8, 0.3, 1), background 0.15s, color 0.15s;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }

.btn--navy   { background: var(--navy);   color: var(--cream); }
.btn--navy:hover   { background: var(--cream); color: var(--navy); }
.btn--yellow { background: var(--yellow); color: var(--navy); }
.btn--yellow:hover { background: var(--cream-hi); }
/* the denser pass, so the label clears 4.5:1 at button size (4.92) */
.btn--red    { background: var(--red-deep); color: var(--cream-hi); }
.btn--red:hover    { background: var(--navy); color: var(--cream-hi); }

/* drawn in the world's own stroke weight, not a unicode glyph */
.btn__out {
  width: 1em;
  height: 1em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.7;
  stroke-linecap: square;
  stroke-linejoin: miter;
  transition: transform 0.15s cubic-bezier(0.2, 0.8, 0.3, 1);
}
/* the arrow marks a link that leaves the sheet, so on hover it goes that way */
.btn:hover .btn__out,
.foot__link:hover .btn__out { transform: translate(2px, -2px); }

.offsite {
  margin-top: 0.85rem;
  font-size: 0.94rem;
  color: var(--ink-soft);
}
.prose--onred .offsite { color: var(--ink-on-red); }

/* ================================================ THE OFFER : HOIST */
.hoist {
  position: relative;
  background: var(--cream);
  padding: clamp(2.6rem, 6vw, 4.5rem) var(--gutter) clamp(2.2rem, 5vw, 3.6rem);
  border-bottom: var(--keyline) solid var(--navy);
  overflow: hidden;
}

.hoist__line {
  position: absolute;
  left: 0; right: 0;
  top: clamp(2.6rem, 6vw, 4.5rem);
  height: var(--keyline);
  background: var(--navy);
}

.hoist__flags {
  position: relative;
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: clamp(0.5rem, 1.6vw, 1.3rem);
  max-width: 1280px;
  margin: 0 auto;
}

.flag {
  position: relative;
  display: grid;
  justify-items: center;
  align-content: start;
  gap: 0.7rem;
  padding: clamp(1.1rem, 2.4vw, 1.8rem) 0.6rem clamp(1.4rem, 3vw, 2.2rem);
  clip-path: polygon(0 0, 100% 0, 100% 86%, 50% 100%, 0 86%);
  transform: translateY(-14%);
  /* the pennant hangs from the halyard, so it swings from its head, not its centre */
  transform-origin: 50% 0;
  opacity: 0;
  /* The run up the halyard and the wind are separate properties on purpose: the
     hover swing is `rotate`, so it never inherits the entrance's 0.62s duration
     or the per-flag stagger delay below. */
  transition:
    transform 0.62s cubic-bezier(0.16, 0.84, 0.28, 1),
    opacity 0.42s ease-out,
    rotate 0.2s cubic-bezier(0.2, 0.8, 0.3, 1);
}
.hoist.is-hoisted .flag { transform: translateY(0); opacity: 1; }
.hoist.is-hoisted .flag:nth-child(1) { transition-delay: 0.00s, 0.00s, 0s; }
.hoist.is-hoisted .flag:nth-child(2) { transition-delay: 0.07s, 0.07s, 0s; }
.hoist.is-hoisted .flag:nth-child(3) { transition-delay: 0.14s, 0.14s, 0s; }
.hoist.is-hoisted .flag:nth-child(4) { transition-delay: 0.21s, 0.21s, 0s; }
.hoist.is-hoisted .flag:nth-child(5) { transition-delay: 0.28s, 0.28s, 0s; }

/* once they are flying, a flag catches the wind under the pointer */
.hoist.is-hoisted .flag:hover { rotate: 1.6deg; }

@media (prefers-reduced-motion: reduce) {
  .flag { transform: none; opacity: 1; transition: none; }
  .hoist.is-hoisted .flag:hover { rotate: none; }
}

.flag--red    { background: var(--red-deep); color: var(--cream-hi); }
.flag--cream  { background: var(--cream-lo); color: var(--navy); }
.flag--yellow { background: var(--yellow); color: var(--navy); }
.flag--navy   { background: var(--navy);   color: var(--cream-hi); }

.flag img {
  height: clamp(74px, 11vw, 132px);
  width: auto;
}

.flag__word {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(0.82rem, 1.5vw, 1.15rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-align: center;
}

/* a flag can itself be the link (the food flag, pending the online menu):
   the anchor must not add a box of its own or it breaks the grid stack */
.flag__link {
  display: contents;
  color: inherit;
  text-decoration: none;
}
.flag__link:hover .flag__word,
.flag__link:focus-visible .flag__word { text-decoration: underline; text-underline-offset: 0.2em; }
.flag__link:focus-visible { outline: none; }
.flag__link:focus-visible .flag__word { outline: 2px solid currentColor; outline-offset: 4px; }

/* ==================================================== BANDS & SPLITS */
.band { padding: var(--band-y) 0; }
.band--cream { background: var(--cream); }
.band--sage  { background: var(--sage); }
/* the kayak section gets its own committed green field, cream copy on it */
.band--green { background: var(--green); color: var(--ink-on-red); }
.band--green .prose h2 { color: var(--cream-hi); }
.band--green .prose .lede { color: var(--ink-on-red); }
.band--green .prose p { color: var(--ink-on-red); }
.band--green .offsite { color: var(--ink-on-red); }
.band--green .btn--navy { background: var(--cream-hi); color: var(--green); border-color: var(--cream-hi); }
.band--green .btn--navy:hover { background: var(--yellow); color: var(--navy); border-color: var(--yellow); }
.band--green :focus-visible { outline-color: var(--yellow); }
.band--red   { background: var(--red-deep); color: var(--ink-on-red); }

.band__inner {
  width: min(100% - (var(--gutter) * 2), 1180px);
  margin-inline: auto;
}

.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.split--reverse > *:first-child { order: 2; }
.split--reverse > *:last-child  { order: 1; }

.prose { display: grid; justify-items: start; gap: 0; max-width: var(--measure); }
.prose h2 { font-size: var(--step-4); margin-bottom: 1.1rem; }
.prose .lede {
  font-size: var(--step-2);
  line-height: 1.42;
  margin-bottom: 0.9rem;
}
.prose p { margin-bottom: 1.35rem; color: var(--ink-soft); line-height: 1.66; }
.prose .lede { color: var(--ink); }
.prose .sub {
  font-size: var(--step-3);
  margin-top: 0.6rem;
  margin-bottom: 0.8rem;
}
.prose--onred p,
.prose--onred .lede { color: var(--ink-on-red); }
.prose--onred h2 { color: var(--cream-hi); }

/* halftone photographs print as plates: a cream border and a keyline */
.plate {
  margin: 0;
  background: var(--cream-hi);
  padding: 10px;
  border: var(--keyline) solid var(--navy);
}
.plate img { width: 100%; }

/* café: the plate prints first, the two screened cut-outs sit over its lower edge */
.bakes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: clamp(1rem, 2.4vw, 1.8rem);
}
.bakes .plate--tall { grid-column: 1 / -1; }
.bake {
  position: relative;
  z-index: 2;
  margin: -18% 0 0;
  display: grid;
  justify-items: center;
  gap: 0.4rem;
}
.bake img {
  width: 100%;
  max-width: 220px;
  filter: drop-shadow(0 10px 16px rgba(31, 42, 68, 0.26));
  transition: transform 0.15s cubic-bezier(0.2, 0.8, 0.3, 1);
}
/* cut-outs are objects sitting on the plate: they lift the button's 2px */
.bake:hover img { transform: translateY(-2px); }
.bake figcaption {
  font-family: var(--font-display);
  font-size: 0.86rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

/* drinks: a plate with a cut-out standing in front of it */
.drinkstack { position: relative; }
.drinkstack__cut {
  position: absolute;
  left: -3%;
  bottom: -9%;
  width: clamp(88px, 15vw, 168px);
  height: auto;
  filter: drop-shadow(0 12px 18px rgba(31, 42, 68, 0.28));
}

/* ------------------------------------------------------------- event */
.event { display: grid; justify-items: start; gap: 0; max-width: 46rem; }
.event h2 { font-size: var(--step-4); margin-bottom: 1.1rem; }
.event .lede { font-size: var(--step-2); line-height: 1.42; margin-bottom: 0.9rem; }
.event p { margin-bottom: 1.4rem; color: var(--ink-soft); }
.event .lede { color: var(--ink); }

/* ------------------------------------------------------------- quote */
.quote {
  position: relative;
  background: var(--yellow);
  padding: clamp(3rem, 7vw, 5.5rem) 0;
  border-top: var(--keyline) solid var(--navy);
  border-bottom: var(--keyline) solid var(--navy);
}
.quote blockquote { margin: 0; max-width: 48rem; }
.quote p {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--step-3);
  line-height: 1.16;
  text-transform: uppercase;
  color: var(--navy);
  margin-bottom: 1rem;
}
.quote footer {
  font-family: var(--font-body);
  font-style: italic;
  font-size: var(--step-1);
  color: var(--navy-lo);
}

/* the steamer sails off the yellow band's bottom-right corner, its hull
   riding the seam where the yellow meets the footer's navy — the navy
   reads as the water it floats on. z-index lifts it clear of the footer
   (position:relative, stacked in DOM after .quote) */
.quote__boat {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(-34px, -3vw, -18px);
  z-index: 5;
  width: clamp(140px, 18vw, 260px);
  height: auto;
  filter: drop-shadow(0 10px 16px rgba(31, 42, 68, 0.28));
  pointer-events: none;
}

/* ============================================================ FOOTER */
.foot {
  position: relative;
  background: var(--navy);
  color: var(--cream);
  padding-top: calc(clamp(58px, 7vw, 96px) + clamp(2rem, 4vw, 3.2rem));
  overflow: hidden;
}

/* a slim garland printed along the footer's top edge, never over the copy */
.foot__ivy {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: clamp(58px, 7vw, 96px);
  background-image: url("Assets/site/illus-ivy-garland.png");
  background-repeat: repeat-x;
  background-position: center top;
  background-size: auto 100%;
  opacity: 0.92;
  pointer-events: none;
}

.foot__grid {
  position: relative;
  display: grid;
  grid-template-columns: 1.3fr 1fr 1fr 1fr;
  gap: clamp(1.6rem, 3.5vw, 3rem);
  padding-block: clamp(1.5rem, 4vw, 3rem) clamp(2.5rem, 6vw, 4rem);
}

.foot__logo { width: min(190px, 100%); height: auto; }
.foot__tag {
  margin-top: 0.8rem;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 1.18rem;
  text-transform: uppercase;
  letter-spacing: 0.19em;
  color: var(--yellow);
}

.foot h2 {
  font-size: var(--step-1);
  letter-spacing: 0.16em;
  color: var(--yellow);
  margin-bottom: 0.85rem;
}
.foot p { margin-bottom: 0.5rem; color: var(--cream); }
.foot__addr { line-height: 1.5; }
.foot__hours { font-family: var(--font-display); font-size: var(--step-1); text-transform: uppercase; letter-spacing: 0.05em; }
.foot__note { font-size: 0.88rem; color: var(--sage); margin-top: 0.4rem; }

.foot__link {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--cream);
  text-decoration: underline;
  text-decoration-color: rgba(240, 231, 210, 0.45);
  transition: color 0.16s, text-decoration-color 0.16s;
}
.foot__link:hover { color: var(--yellow); text-decoration-color: var(--yellow); }

.foot__bottom {
  position: relative;
  border-top: 1px solid rgba(240, 231, 210, 0.22);
  padding: 1.2rem var(--gutter);
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1.5rem;
  justify-content: space-between;
  font-size: 0.84rem;
  color: var(--sage);
}
.foot__bottom p { margin: 0; color: inherit; }

/* The NPF emblem is an issued mark, reproduced unaltered — see The Issued Mark
   rule. It is the one raster on the page that carries no treatment and sits
   outside the five inks, so it is kept small and last, in the bottom corner.
   Its source PNG is a fully opaque square right into the corners, which reads
   as a white box against the navy footer. The rounded corner here clips that
   opaque margin to the card's own curvature rather than editing the issued
   file — the pixels stay untouched, only the display is masked. */
.foot__emblem {
  flex: none;
  width: clamp(76px, 8vw, 100px);
  height: auto;
  border-radius: 8%;
}

/* ======================================================== RESPONSIVE */

/* ---------------------------------------------- THE MASTHEAD IN THE SHEET
   Wide enough that the nav clears the cut: the masthead leaves the flow and
   sits in the sheet's own nav strip, so the sheet starts at the top edge of
   the viewport and the yellow and navy bands run off the top-right corner —
   the comp's composition. Below this the nav needs the whole line for itself
   and stays in flow above the sheet, which still bleeds left, right and down.
   1100px is where the six nav items plus the logo still fit left of the cut
   (they need ~582px of the ~658px there is). */
@media (min-width: 1100px) {
  :root {
    --mast-h: 6.6rem;
    /* the sheet now carries the nav strip too, so it grows by that much and
       the poster below the nav stays the size it was */
    --sheet-h: min(84vh, 820px);
  }

  body { position: relative; }

  .masthead {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: var(--mast-h);
    padding-block: 0;
    background: none;
    z-index: 5;
  }
  .masthead__logo img { height: 4.4rem; }
  /* packed left — everything in the strip has to clear the cut */
  .masthead__nav { margin-left: 0; margin-right: auto; }
  .masthead__nav ul { gap: clamp(0.9rem, 1.7vw, 1.6rem); }

  /* The one control that sits right of the cut, over the navy band and the
     scene. It carries its own stock so it never loses its ground — the comp
     boxes it in the same corner for the same reason. */
  .lang {
    background: var(--cream);
    border: var(--keyline) solid var(--navy);
    padding: 0.15rem 0.4rem;
  }

  .sheet__notch {
    display: block;
    position: absolute;
    inset: 0;
    z-index: 1;
    /* the red field's own silhouette, so the corner lands on the cut */
    clip-path: polygon(0 0, 63% 0, 34% 100%, 0 100%);
    pointer-events: none;
  }
  /* The strip crosses the whole sheet in the comp, not just the red half: the
     scene starts at the same level the vermilion field does (measured at y=105
     and y=99 on a 1152px comp) and only the two bands run on up to the top
     edge. A second layer, clipped to the scene's own silhouette instead of the
     field's, carries it across — one polygon cannot describe two shapes that
     have the bands between them. */
  .sheet__notch--scene {
    clip-path: polygon(75.8% 0, 100% 0, 100% 100%, 38.6% 100%);
    z-index: 2;
  }

  .sheet__notch i {
    display: block;
    height: var(--mast-h);
    background: var(--cream);
  }

  /* clears the strip in px, not in percent — percentage padding resolves
     against width, and this has to track a height.
     The copy is given the sheet's own height and a flexible third row, so the
     headline and tagline stay a tight pair at the top while the button and the
     address settle at the foot of the field, the way the comp weights it. It
     is a min-height, so where the headline re-wraps and the copy is already
     taller than the sheet, this does nothing at all. */
  .sheet__copy {
    min-height: var(--sheet-h);
    grid-template-rows: auto auto 1fr auto;
    padding-top: calc(var(--mast-h) + 1.4rem);
    padding-bottom: clamp(1.6rem, 3.4vw, 2.6rem);
    padding-left: clamp(2rem, 4.5vw, 4rem);
  }
  .sheet__copy .btn { align-self: end; }

  /* The taper carried the wedge's foot left, from 46.5% to 38.6%, and the
     address is a fixed-size line: below about 1400px it no longer clears the
     cut, and cream lettering was crossing the yellow band. Wrapping it is the
     only lever there is — its size is a contrast decision, 19.2px at 700 so it
     qualifies as large text at 3.47:1, and must not be reduced. */
  .sheet__addr { max-width: 35vw; }
}

@media (max-width: 1000px) {
  .foot__grid { grid-template-columns: 1fr 1fr; }
}

@media (max-width: 860px) {
  .masthead { flex-wrap: wrap; row-gap: 0.6rem; }
  .masthead__nav { order: 3; width: 100%; margin-left: 0; }
  .masthead__nav ul { justify-content: space-between; gap: 0.5rem 0.9rem; }
  .lang { margin-left: auto; }

  /* The sheet stops cutting diagonally and stacks. The scene returns to normal
     flow and the bands become real boxes: percentage padding resolves against
     WIDTH, so it can never be trusted to clear a height-cut clip-path. */
  .sheet {
    min-height: 0;
    display: grid;
    grid-template-rows: auto auto auto auto;
    background: var(--red);
  }
  .sheet__red,
  .sheet__yellow,
  .sheet__navy { position: static; clip-path: none; inset: auto; }

  .sheet__scene {
    position: static;
    clip-path: none;
    grid-row: 1;
    aspect-ratio: 2 / 1;
  }
  /* Reset the desktop wedge-box rule in full. Leaving `position: absolute`
     and the 43%/57% offsets in place floated the scene over the whole sheet
     and put the headline on the cream city hall at 2:1. */
  .sheet__scene img {
    position: static;
    left: auto;
    width: 100%;
    height: 100%;
    object-position: center;
  }

  .sheet__yellow { grid-row: 2; height: 14px; }
  .sheet__navy   { grid-row: 3; height: 12px; }
  .sheet__red    { display: none; }

  .sheet__copy {
    grid-row: 4;
    max-width: none;
    padding-top: clamp(1.6rem, 6vw, 2.4rem);
  }
  .sheet__ghost {
    top: auto;
    bottom: 6%;
    /* inside the border: on mobile no diagonal crops it, so the sheet edge
       would be doing the cutting, which is not the comp's device */
    left: 4%;
    font-size: clamp(3.6rem, 20vw, 8rem);
    transform: rotate(-13deg);
    transform-origin: left bottom;
    /* no comp governs mobile; keep it clearly under the copy */
    -webkit-text-stroke-width: 2px;
    -webkit-text-stroke-color: rgba(249, 238, 212, 0.2);
  }

  .split { grid-template-columns: 1fr; }
  .split--reverse > *:first-child,
  .split--reverse > *:last-child { order: 0; }

  .hoist__flags { grid-template-columns: repeat(5, 1fr); gap: 0.35rem; }
  .flag { padding-inline: 0.25rem; }
}

@media (max-width: 620px) {
  .hoist__flags { grid-template-columns: repeat(2, 1fr); gap: 0.6rem; }
  .hoist__line { display: none; }
  .flag:nth-child(5) { grid-column: 1 / -1; }

  .bakes { grid-template-columns: 1fr 1fr; }
  .drinkstack__cut { left: 0; bottom: -6%; }
  .foot__grid { grid-template-columns: 1fr; }
  .sheet__ghost { -webkit-text-stroke-width: 1.5px; }
}

@media (max-width: 420px) {
  .masthead__nav ul { gap: 0.4rem 0.7rem; }
  .masthead__nav a { font-size: 0.8rem; letter-spacing: 0.1em; }
}

/* ==================================================== MOTION YIELDS */
/* DESIGN.md: every hover and focus change yields to prefers-reduced-motion.
   Colour and keyline changes stay — they carry meaning, not motion. */
@media (prefers-reduced-motion: reduce) {
  .btn:hover { transform: none; }
  .btn:hover .btn__out,
  .foot__link:hover .btn__out { transform: none; }
  .bake:hover img { transform: none; }
  .masthead__nav a:hover .pennant { transform: rotate(-4deg); }
}

@media print {
  body::after, .lang, .skip { display: none; }
  .foot { background: #fff; color: #000; }
}
