/* ============================================================
   STEGO COFFEE
   ------------------------------------------------------------
   TYPE RULE — read before editing.

   There are exactly seven type sizes, defined as tokens below.
   Nothing in this file sets a font-size to a raw value; every
   rule references one of --t-*. If a new element seems to need
   an eighth size, it almost certainly needs an existing one.

   VOICE RULE — uppercase display type is reserved for page
   statements: the home hero, page titles, the footer wordmark.
   Content headings (cards, panels) are sentence case. Two
   voices, so size isn't carrying the hierarchy alone.

   The statement voice is set in Boiga. Everything else — body copy,
   labels, data — is IBM Plex Mono. Boiga is a licensed webfont; see
   section 00 before touching /fonts/.

   Contents
     00  Fonts
     01  Tokens
     02  Reset & base
     03  Type primitives
     04  Layout & section headings
     05  Header & nav
     06  Buttons
     07  Home hero
     08  Interior page hero
     09  Cards
     10  Learn checklist
     11  Footer
     12  Responsive
     13  Reduced motion
   ============================================================ */


/* == 00  Fonts ============================================= */

/* Boiga v0.3 by Kel Troughton / Overlap Type,
   bought through Future Fonts. Self-hosted from /fonts/ because the
   licence requires it: only the webfonts from the purchased package,
   only on domains we control directly. Linking the desktop OpenType
   files is prohibited, so the OTFs are never committed. No traffic or
   visitor cap applies — the licence is scoped by user count instead.
   See fonts/README.txt before touching that directory.

   A/B/C/D are not stylistic variants — they are the family's four
   weights, usWeightClass 200 / 400 / 600 / 800. A is ExtraLight and D
   is ExtraBold. A still reads heavy: this is a display family, and its
   lightest cut is most faces' bold. That is why running text is set in
   IBM Plex Mono and not here. */

/* Narrow, the statement voice. Only A is shipped: .display asks for 400
   and nothing nests emphasis inside a page statement. If that changes,
   add NarrowFillB on the 600-900 range and it will work unchanged. */
@font-face {
  font-family: "Boiga";
  src: url("fonts/Boiga_V3-NarrowFillA.woff2") format("woff2"),
       url("fonts/Boiga_V3-NarrowFillA.woff") format("woff");
  font-weight: 100 500;
  font-style: normal;
  font-display: swap;
}

/* Only the Narrow cut is still loaded. The Regular cuts carried the label
   voice until labels moved to IBM Plex Mono; leaving them declared would
   ship two webfonts nothing asks for. */


/* == 01  Tokens ============================================ */

:root {
  /* ---- type scale: the only seven sizes in the site ---- */
  --t-display: clamp(3rem, 8vw, 5.5rem);      /* home hero only        */
  --t-h1:      clamp(2.25rem, 5vw, 3.25rem);  /* page titles, wordmark */
  --t-h2:      clamp(1.5rem, 2.8vw, 2.125rem);/* post titles, posters  */
  --t-h3:      1.25rem;                       /* card & section titles */
  --t-lead:    1.1875rem;                     /* standfirst / intro    */
  --t-body:    1rem;                          /* body copy             */
  --t-small:   0.75rem;                       /* every mono label      */

  --lh-display: 0.92;
  --lh-tight:   1.18;
  --lh-body:    1.6;

  /* ---- ground ----
     Brand Color System v3. Every value below is from that system; where
     one could not do the job its own description assigns it, the source
     colour is kept for fills and a darkened companion carries the text.
     Ratios are against Canvas. */
  --paper:      #FFF8ED;   /* Canvas        page ground                  */
  --card:       #F5F0E8;   /* Card          panels, subtle lift          */
  --tray:       #EAE4D8;   /* Tray          sidebars, footers, insets    */
  --fossil:     #1A1D16;   /* Fossil        dark surfaces                */
  --fossil-2:   #2A2D24;   /* Fossil Soft   raised dark surfaces         */

  --cream:      #FFF8ED;   /* Chalk — text on dark. Not a card colour;
                              nothing in this file uses it as a ground.  */
  --chalk-2:    #D4D0C6;   /* Chalk Soft    secondary text on dark       */

  --ink:        #1A1D16;   /* Ink           16.16:1                      */
  --ink-2:      #3D4A38;   /* Ink Soft       8.90:1                      */
  --ink-3:      #70726A;   /* Ink Faded darkened 4 points. The source
                              #7A7D74 is 3.97:1 and its stated job is
                              captions and timestamps — small text.      */
  --line:       #D4CFC5;   /* Outline                                    */
  --line-hard:  #A8A49A;   /* Outline Strong                             */
  --line-soft:  #E8E3DA;   /* Outline Subtle                             */

  /* ---- accent ----
     Stego Teal is the primary, and it is a FILL colour: 2.12:1 on Canvas
     means it cannot be text at any size. Used as a ground it is superb —
     Ink on Teal is 7.64:1. --sea-deep is the darkened teal for the cases
     where teal has to be type. */
  --teal:       #5BBFA0;   /* Stego Teal    fills, CTAs, brand moments   */
  --sea:        #3A8E72;   /* Stego Deep    focus ring, 3.76:1 (UI ok)   */
  --sea-deep:   #337C63;   /* darkened       4.73:1 as text              */

  --roast:      #C7422E;   /* Ember          4.69:1                      */
  --roast-deep: #8F2A1E;   /* Ember Deep     7.90:1                      */
  --sand:       #E8944A;   /* Plate Orange   surface only, 2.27:1        */
  --gold:       #F4C24D;   /* Sunstone       surface only                */
  --berry:      #D4718A;   /* Berry          surface only                */
  --dusk:       #9B7EC8;   /* Dusk           surface only                */
  --leaf:       #337C63;   /* Fresh, darkened to match --sea-deep        */

  /* ---- status ---- */
  --ok:         #337C63;  --ok-bg:      #DFF2EB;
  --warn:       #E8944A;  --warn-bg:    #FFF0E0;
  --danger:     #C7422E;  --danger-bg:  #FCEAE6;
  --info:       #5A9ED6;  --info-bg:    #E4F0FA;

  /* ---- card tones ----
     The system's DATA series, used sequentially as it intends. Tone
     encodes origin. Ink clears AA on all six, 5.05:1 at worst. */
  --tone-eth:   #5BBFA0;   /* Series A   7.64:1 */
  --tone-per:   #5A9ED6;   /* Series B   5.93:1 */
  --tone-ken:   #E8944A;   /* Series C   7.12:1 */
  --tone-png:   #D4718A;   /* Series D   5.30:1 */
  --tone-yem:   #9B7EC8;   /* Series E   5.05:1 */
  --tone-bra:   #F4C24D;   /* Series F  10.29:1 */

  /* ---- typefaces ----
     Two families, three jobs. Plex Mono is a real monospace, which is
     what makes tabular-nums work on the coffee-card spec rows. */
  --display:   "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  --mono:      "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  /* Statement voice only. Falls back to the body face so a failed load
     degrades quietly rather than to a system serif. */
  --statement: "Boiga", "IBM Plex Mono", ui-monospace, Menlo, monospace;

  --gutter: clamp(1.25rem, 4vw, 3rem);
  --maxw: 1180px;
  --radius: 20px;
}


/* == 02  Reset & base ====================================== */

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  /* Every weight on this page is a real drawn cut, so nothing needs
     synthesising. This stops a browser inventing one if a face fails. */
  font-synthesis: none;
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--display);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a {
  color: inherit;
  text-decoration: none;
}

img,
svg {
  max-width: 100%;
  display: block;
}

:focus-visible {
  outline: 3px solid var(--sea);
  outline-offset: 3px;
  border-radius: 2px;
}


/* == 03  Type primitives =================================== */

/* The single small size. Nav, buttons, tags, dates, meta,
   section headings, sidebar keys — all of it is this. */
.label {
  font-family: var(--mono);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--ink-2);
  margin: 0;
}

.label--roast { color: var(--roast-deep); }
.label--sea   { color: var(--sea-deep); }
.label--quiet { color: var(--ink-3); }

/* Statement voice: uppercase, tight, big. Used sparingly.
   Boiga is already heavy and tightly fitted, so it needs far less
   negative tracking than a text face would, and no bold at all. */
.display {
  font-family: var(--statement);
  font-weight: 400;
  font-synthesis: none;
  text-transform: uppercase;
  letter-spacing: -0.005em;
  line-height: var(--lh-display);
  margin: 0;
  text-wrap: balance;
}

/* Content voice: sentence case, still bold, much calmer. */
.title {
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: var(--lh-tight);
  margin: 0;
  text-wrap: balance;
}

.lead {
  max-width: 56ch;
  font-size: var(--t-lead);
  line-height: 1.5;
  color: var(--ink-2);
  text-wrap: pretty;
}


/* == 04  Layout & section headings ========================= */

.wrap {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section {
  padding: clamp(2.75rem, 6vw, 4.5rem) 0;
}

.section--tight {
  padding-top: 0;
}

/* A section heading is a quiet mono label on a hairline rule.
   The content below it is what should be large. */
.section-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  flex-wrap: wrap;
  padding-bottom: 0.75rem;
  border-bottom: 1px solid var(--line-hard);
  margin-bottom: 2rem;
}

.section-head h2 {
  font-family: var(--mono);
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.4;
  color: var(--ink);
  margin: 0;
}

/* The post list draws its own rules, so it sits flush. */
.section-head--flush {
  margin-bottom: 0;
}

.section-link {
  font-family: var(--mono);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sea-deep);
  transition: color 140ms ease;
}

.section-link:hover {
  color: var(--ink);
}

/* Plain rule inside body copy — same hairline as a section-head,
   just without the label riding on it. */
hr {
  border: none;
  border-top: 1px solid var(--line-hard);
  margin: 0 0 1.75rem;
}


/* == 05  Header & nav ====================================== */

/* Dark ground so the mark's paper-colored circle actually reads as a
   badge instead of blending into the page — the same reason archived
   cards and the card back's header bar are dark. */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--fossil) 92%, transparent);
  backdrop-filter: blur(14px) saturate(1.2);
  border-bottom: 1px solid rgba(255, 248, 237, 0.1);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 64px;
}

/* Same brand-group layout as a card's sticker header — logo, then a
   Boiga name over a small mono label — just in ink on the page ground
   instead of chalk on a colored one. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
}

.brand svg {
  width: 40px;
  height: 40px;
  flex: none;
  /* Force a true circular clip rather than trusting the mark's own
     circle path to render clean at every fluid size — at some widths
     it was leaving a faint straight seam where the path's anti-aliasing
     met the element's edge. */
  border-radius: 50%;
  overflow: hidden;
}

.brand-text {
  display: flex;
  flex-direction: column;
  gap: 0.05em;
  color: var(--cream);
}

.brand-name {
  font-size: var(--t-h3);
  line-height: 1;
}

.brand-sub {
  font-family: var(--mono);
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.7;
}

.nav-links {
  display: flex;
  align-items: center;
  gap: 0.25rem;
  flex-wrap: wrap;
}

.nav-links a {
  font-family: var(--mono);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--chalk-2);
  padding: 0.5rem 0.7rem;
  border-radius: 999px;
  transition: color 140ms ease;
}

.nav-links a:hover {
  color: var(--cream);
}

.nav-links a[aria-current="page"] {
  color: var(--cream);
  background: rgba(255, 248, 237, 0.12);
}


/* == 06  Buttons =========================================== */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--mono);
  font-size: var(--t-small);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 0.9rem 1.5rem;
  border-radius: 999px;
  border: 1.5px solid var(--line-hard);
  cursor: pointer;
  transition: background 160ms ease, color 160ms ease;
}

.btn svg {
  width: 13px;
  height: 13px;
}

.btn--solid {
  background: var(--teal);
  color: var(--ink);
}

.btn--solid:hover {
  background: var(--sea);
  color: var(--cream);
}

.btn--ghost {
  background: transparent;
  color: var(--ink);
}

.btn--ghost:hover {
  background: var(--ink);
  color: var(--cream);
}


/* == 07  Home hero ========================================= */

.hero {
  padding: clamp(2rem, 5vw, 4rem) 0 clamp(2.5rem, 5vw, 4rem);
}

.hero h1 {
  font-size: var(--t-display);
}


/* == 08  Interior page hero ================================ */

.page-hero {
  padding: clamp(2rem, 4vw, 3rem) 0 clamp(1.5rem, 3vw, 2.5rem);
}

.page-hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}

.page-hero h1 {
  font-size: var(--t-h1);
  margin-top: 1rem;
}

.page-hero .lead {
  margin: 1.25rem 0 0;
}

.page-hero-art svg {
  width: 100%;
  height: auto;
}

.page-hero--article {
  max-width: 46rem;
}

.article-meta {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-wrap: wrap;
}

.article-meta .sep {
  color: var(--ink-3);
}

.article-intro {
  margin: 1.25rem 0 0;
  max-width: 60ch;
  font-size: var(--t-lead);
  line-height: 1.5;
  color: var(--ink-2);
  text-wrap: pretty;
}


/* == 09  Cards ============================================= */

.grid-3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1rem;
}

.card {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.25rem, 2.5vw, 1.6rem);
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  transition: border-color 180ms ease;
}

.card:hover {
  border-color: var(--line-hard);
}

.card h3 {
  font-size: var(--t-h3);
}

.card p {
  margin: 0;
  color: var(--ink-2);
}


/* ---- coffee cards ----
   One card per lot. Cards start in the current grid in the markup and
   JavaScript moves archived ones, so the page is complete and readable
   with scripting off — flipping is an enhancement, not where content
   lives; both faces are in the DOM either way.

   Each lot is one sticker (.coffee-flip) that flips in place: a front
   (.coffee-face) carrying the brand mark, card number, origin, and
   flavor notes, and a back (.coffee-face-back) carrying Producer/Farm
   plus Process and Variety where recorded, and the archive control.
   Front and back are the same fixed 580:300 box so the flip has no
   seam — .coffee-flip-inner is the one thing that actually rotates,
   with both faces absolutely filling it and backface-visibility
   hiding whichever one is turned away.

   Colorway = origin, taken straight from the brand accents rather than
   the separate --tone-* data series: Ethiopia/Teal, Kenya/Orange(sand),
   Papua New Guinea/Berry, Yemen/Dusk, Brazil/Sunstone(gold) all land on
   the same hue the data tones already used. Peru has no brand accent of
   its own in this set, so it takes the one otherwise-unused colorway,
   Ember(roast) — the only real reassignment among the six. Archived lots
   use Grayscale: the paper ground, ink stays full strength rather than
   fading, matching how the source component treats it. */

.coffee-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
  gap: clamp(1.5rem, 3vw, 2.25rem);
}

.coffee {
  display: flex;
  flex-direction: column;
  color: var(--ink);
  container-type: inline-size;
}

/* ---- flip mechanics ----
   A div with role="button" rather than a real <button>, because the
   archive control has to live inside it (a <button> can't nest one).
   script.js drives it off aria-pressed — that one attribute is both
   the accessible state and the CSS hook for the rotation. The global
   reduced-motion rule in section 18 already zeroes this transition
   for anyone who asked for that, so no extra guard is needed here. */

.coffee-flip {
  display: block;
  width: 100%;
  padding: 0;
  cursor: pointer;
  perspective: 1400px;
}

.coffee-flip:focus-visible {
  outline: 3px solid var(--sea);
  outline-offset: 4px;
  border-radius: var(--radius);
}

.coffee-flip-inner {
  position: relative;
  width: 100%;
  /* Taller than the source's 4:3 — stacking notes in one column instead
     of a 2x2 grid roughly doubled how much height 4 of them need, and
     Boiga still renders taller than the fallback face any measurement
     of mine sees it as. This box has no overflow allowance (front and
     back must match exactly for the flip), so the margin has to be
     real, not "just barely fits" on my own numbers. */
  aspect-ratio: 6 / 5;
  transform-style: preserve-3d;
  transition: transform 500ms ease;
}

.coffee-flip[aria-pressed="true"] .coffee-flip-inner {
  transform: rotateY(180deg);
}

/* ---- shared sticker shape ---- */

.coffee-face,
.coffee-face-back {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  /* Every clamp() in this component and the back below is a real
     proportion of the source's 1200px-wide card (e.g. 41px padding =
     3.42cqw), not a guess — so the max only exists as a sanity ceiling
     well past any width the grid actually produces, and cqw does the
     real work at every size in between. A tight max here is what broke
     "fills the card" on a wide single-column layout: it capped growth
     before the card ran out of room. */
  padding: clamp(0.6rem, 3.42cqw, 2.2rem);
  border: 3px solid var(--ink);
  border-radius: var(--radius);
  box-shadow: 0 10px 24px 0 rgb(26 29 22 / 0.17);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}

.coffee-face-back {
  transform: rotateY(180deg);
  pointer-events: none;
}

.coffee-flip[aria-pressed="true"] .coffee-face-back {
  pointer-events: auto;
}

/* ---- front ---- */

.coffee-face {
  --face-tone: var(--teal);
  --face-ink: var(--ink);
  gap: clamp(0.4rem, 3.42cqw, 2.2rem);
  justify-content: space-between;
  background: var(--face-tone);
  border-color: var(--face-ink);
  color: var(--face-ink);
}

.coffee[data-origin="kenya"]  .coffee-face { --face-tone: var(--sand); }
.coffee[data-origin="peru"]   .coffee-face { --face-tone: var(--roast); }
.coffee[data-origin="png"]    .coffee-face { --face-tone: var(--berry); }
.coffee[data-origin="yemen"]  .coffee-face { --face-tone: var(--dusk); }
.coffee[data-origin="brazil"] .coffee-face { --face-tone: var(--gold); }

/* Retired lots invert instead of fading: a near-black ground with the
   same chalk ink the colored fronts already use for their notes and
   badge, rather than a quiet paper card. */
.coffee[data-archived="true"] .coffee-face {
  --face-tone: var(--fossil);
  --face-ink: var(--cream);
}

.coffee-face-header {
  display: flex;
  flex-direction: column;
  gap: clamp(0.5rem, 2.42cqw, 1.6rem);
}

.coffee-face-toprow {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
}

.coffee-face-brand {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.coffee-face-brand svg {
  width: clamp(28px, 12.33cqw, 100px);
  height: clamp(28px, 12.33cqw, 100px);
  flex: none;
  /* See .brand svg — same fix for the same seam, just at a fluid size. */
  border-radius: 50%;
  overflow: hidden;
}

.coffee-face-brand-text {
  display: flex;
  flex-direction: column;
  gap: 0.1em;
}

/* Wordmark is always chalk — it's the one thing on the front that doesn't
   flip with the light/dark ground, same as the notes and the badge. */
.coffee-face-brand-text .display {
  font-size: clamp(1.2rem, 8cqw, 4.5rem);
  color: var(--cream);
}

.coffee-face-brand-text span {
  font-family: var(--mono);
  font-size: clamp(0.55rem, 1.58cqw, 1.15rem);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--face-ink);
  opacity: 0.7;
}

.coffee-face-number {
  flex: none;
  font-family: var(--mono);
  font-weight: 700;
  font-size: clamp(0.7rem, 3.42cqw, 1.9rem);
  color: var(--cream);
  border: 2px solid var(--cream);
  border-radius: 999px;
  padding: clamp(0.15rem, 0.67cqw, 0.5rem) clamp(0.4rem, 2.08cqw, 1.4rem);
  white-space: nowrap;
}

.coffee-face-rule {
  border: none;
  border-top: 2px solid var(--face-ink);
  width: 100%;
  margin: 0;
}

.coffee-face-body {
  display: flex;
  flex-direction: column;
  flex: 1 0 0;
  min-height: 0;
  gap: clamp(0.3rem, 1.42cqw, 1rem);
  padding-top: clamp(0.2rem, 1.42cqw, 1rem);
}

.coffee-face-origin-label {
  margin: 0;
  font-family: var(--mono);
  font-size: clamp(0.6rem, 1.92cqw, 1.3rem);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.6;
}

.coffee-face-origin {
  margin: 0;
  font-size: clamp(1.2rem, 8cqw, 4.5rem);
  line-height: 1.2;
  color: var(--face-ink);
}

/* One column, full width — the source's own layout now that each card
   only carries 3-4 notes, rather than the 2x2 grid built for up to 6. */
.coffee-face-notes {
  display: flex;
  flex-direction: column;
  gap: clamp(0.1rem, 0.9cqw, 0.6rem);
}

.coffee-face-notes p {
  margin: 0;
  font-size: clamp(1rem, 6cqw, 3.4rem);
  line-height: 1.15;
  color: var(--cream);
}

/* ---- back ---- */

.coffee-face-back {
  --back-accent: var(--teal);
  gap: clamp(0.35rem, 2cqw, 0.55rem);
  background: var(--paper);
  color: var(--ink);
}

.coffee[data-origin="kenya"]  .coffee-face-back { --back-accent: var(--sand); }
.coffee[data-origin="peru"]   .coffee-face-back { --back-accent: var(--roast); }
.coffee[data-origin="png"]    .coffee-face-back { --back-accent: var(--berry); }
.coffee[data-origin="yemen"]  .coffee-face-back { --back-accent: var(--dusk); }
.coffee[data-origin="brazil"] .coffee-face-back { --back-accent: var(--gold); }
.coffee[data-archived="true"] .coffee-face-back { --back-accent: var(--cream); }

.coffee-back-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding: clamp(0.35rem, 2cqw, 0.5rem) clamp(0.6rem, 3.4cqw, 0.9rem);
  background: var(--ink);
  border-radius: calc(var(--radius) * 0.55);
}

.coffee-back-header .display {
  font-size: clamp(0.85rem, 4.5cqw, 1.15rem);
  color: var(--cream);
}

.coffee-back-header span {
  font-family: var(--mono);
  font-weight: 700;
  font-size: clamp(0.7rem, 3.4cqw, 0.95rem);
  color: var(--back-accent);
}

.coffee-back-rows {
  margin: 0;
  display: flex;
  flex-direction: column;
}

.coffee-back-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  padding-block: clamp(0.15rem, 1cqw, 0.3rem);
  border-bottom: 1px solid var(--line-hard);
}

.coffee-back-row:last-child {
  border-bottom: none;
}

.coffee-back-row dt {
  font-family: var(--mono);
  font-size: clamp(0.55rem, 2.2cqw, 0.65rem);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-3);
}

.coffee-back-row dd {
  margin: 0;
  font-family: var(--mono);
  font-weight: 700;
  font-size: clamp(0.65rem, 3cqw, 0.8rem);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Pinned to the bottom of the back face — rows above take only the
   height their content needs, this stays put whether there's one row
   or three. */
.coffee-back-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem;
  margin-top: auto;
}

.coffee-back-logo {
  flex: none;
  width: clamp(24px, 10cqw, 36px);
  height: clamp(24px, 10cqw, 36px);
  transform: scaleX(-1);
  /* See .brand svg — same fix for the same seam, just at a fluid size. */
  border-radius: 50%;
  overflow: hidden;
}

/* The back face is paper-coloured, so the badge's own paper disc would
   vanish into it — swap the disc to our dark surface tone and keep the
   eye legible against it. Sand plates and teal body read fine on either. */
.coffee-back-logo circle {
  fill: var(--fossil);
}

.coffee-back-logo path:last-of-type {
  fill: var(--cream);
}

.coffee-archive {
  flex: none;
  font-family: var(--mono);
  font-size: clamp(0.55rem, 2.4cqw, 0.7rem);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  background: none;
  border: 1px solid currentColor;
  border-radius: 999px;
  color: inherit;
  padding: 0.3rem 0.75rem;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 160ms ease;
}

.coffee-archive:hover,
.coffee-archive:focus-visible { opacity: 1; }

.coffee-empty {
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--t-small);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin: 0;
}


/* == 10  Learn checklist =================================== */

.learn-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 3vw, 2.5rem);
  align-items: start;
}

.checklist {
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.25rem, 3vw, 2rem);
}

.progress-shell {
  padding-bottom: 1.25rem;
}

.progress-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 0.6rem;
}

.progress-stage {
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.progress-track {
  position: relative;
  height: 10px;
  border-radius: 999px;
  background: rgba(27, 36, 41, 0.08);
  overflow: hidden;
}

.progress-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0%;
  border-radius: inherit;
  transition: width 320ms ease, background-color 320ms ease;
}

.progress-count {
  margin: 0.6rem 0 0;
}

.category {
  padding-top: 1.5rem;
  margin-top: 1.5rem;
  border-top: 1px solid var(--line);
}

.cat-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1rem;
  margin-bottom: 0.4rem;
}

.cat-title {
  font-size: var(--t-h3);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: var(--lh-tight);
  margin: 0;
}

.cat-meter {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex: none;
}

.cat-track {
  width: 72px;
  height: 6px;
  background: rgba(27, 36, 41, 0.08);
  border-radius: 999px;
  overflow: hidden;
}

.cat-fill {
  height: 100%;
  border-radius: inherit;
  transition: width 320ms ease, background-color 320ms ease;
}

.cat-frac {
  font-family: var(--mono);
  font-size: var(--t-small);
  font-weight: 500;
  color: var(--ink-3);
  min-width: 2.2rem;
  text-align: right;
}

.cat-why {
  margin: 0 0 1rem;
  color: var(--ink-2);
}

.items {
  list-style: none;
  padding: 0;
  margin: 0;
}

.item {
  display: flex;
  align-items: flex-start;
  gap: 0.85rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--line);
}

.item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

/* Accent here is functional — it reports state. */
.check-box {
  width: 1.15rem;
  height: 1.15rem;
  min-width: 1.15rem;
  margin-top: 0.28rem;
  border: 1.5px solid var(--ink-3);
  border-radius: 0.35rem;
  background: transparent;
  position: relative;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease;
}

.check-box.checked {
  background: var(--roast);
  border-color: var(--roast);
}

.check-box.checked::after {
  content: "";
  position: absolute;
  left: 0.3rem;
  top: 0.09rem;
  width: 0.32rem;
  height: 0.6rem;
  border: solid var(--cream);
  border-width: 0 2.5px 2.5px 0;
  transform: rotate(45deg);
}

.item-body {
  flex: 1;
}

.item-head {
  display: flex;
  flex-wrap: wrap;
  gap: 0.65rem;
  align-items: baseline;
}

.item-label {
  cursor: pointer;
  font-weight: 600;
  color: var(--ink);
}

.item-label.checked {
  color: var(--ink-3);
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
}

.item-link {
  font-family: var(--mono);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sea-deep);
}

.item-link:hover {
  color: var(--ink);
}

.item-desc {
  margin-top: 0.2rem;
  color: var(--ink-2);
}

.reset-btn {
  margin-top: 1.5rem;
  background: transparent;
  color: var(--ink-3);
  font-family: var(--mono);
  font-size: var(--t-small);
  font-weight: 500;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 0.7rem 1.15rem;
  cursor: pointer;
  transition: color 140ms ease, border-color 140ms ease;
}

.reset-btn:hover {
  color: var(--ink);
  border-color: var(--line-hard);
}

.focus-stack {
  display: grid;
  gap: 1rem;
}


/* == 11  Footer ============================================ */

.site-footer {
  border-top: 1px solid var(--line-hard);
  padding: clamp(2.5rem, 5vw, 3.5rem) 0 2.5rem;
  margin-top: clamp(2rem, 5vw, 3.5rem);
}

.footer-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 2rem;
  flex-wrap: wrap;
}

.footer-top h2 {
  font-size: var(--t-h1);
}

.footer-note {
  max-width: 42ch;
  color: var(--ink-2);
  margin: 0.6rem 0 0;
}

.footer-bottom {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
  margin-top: 2.5rem;
  padding-top: 1.25rem;
  border-top: 1px solid var(--line);
}

.footer-bottom p {
  margin: 0;
}


/* == 12  Responsive ======================================== */

@media (max-width: 980px) {
  .page-hero-grid,
  .learn-grid,
  .poster-pair,
  .article-shell {
    grid-template-columns: 1fr;
  }

  .page-hero-art {
    max-width: 380px;
  }

  .wayfind,
  .grid-3 {
    grid-template-columns: 1fr;
  }

  .article-sidebar {
    position: static;
  }
}

@media (max-width: 640px) {
  .nav {
    flex-direction: column;
    align-items: flex-start;
    padding-block: 0.75rem;
    gap: 0.4rem;
  }

  .nav-links {
    margin-left: -0.7rem;
  }

  .post {
    grid-template-columns: 2rem minmax(0, 1fr);
    gap: 1rem;
  }

  .cat-head {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
  }
}


/* == 13  Reduced motion ==================================== */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
  }
}
