/* ==========================================================================
   Circular Economy Magazine — prototype design system
   Colour tokens extracted verbatim from the live Webflow stylesheet
   (circular-economy-magazine.webflow.shared.94e9395bf.css, --_ce-mag---*)
   ========================================================================== */

:root{
  /* Black and white, matching the live Issue 2 page
     (circulareconomymag.com/issues/issue-2): a #1d1d1e header on a #f9f9f9
     ground. Ken's call, 2026-09-03 — the purples are gone.

     Green and blue stay. #36aa5e is sampled from the live page's own buttons,
     and #3b8dcc is the article eyebrow the live article layout already uses. */
  --ink:#1d1d1e;          /* the black  */
  --ink-lift:#38383a;     /* hover on a dark ground */
  --paper:#f9f9f9;        /* the white  */
  --paper-2:#efefef;      /* the secondary band, a neutral step off the white */
  --accent:#36aa5e;       /* interaction; same value as --green */

  --green:#36aa5e;
  --blue:#3b8dcc;
  --gray-med-dark:#6b6c6f;   /* #a11y 2026-09-12: was #6d6e71, 4.43:1 on --paper-2
                                (fails WCAG AA's 4.5:1 for normal text - this is
                                what .tag/.cover-hint/.fineprint/.card-foot etc. all
                                use). 2 units darker clears it (4.57:1) with room
                                to spare, and is not a visible colour change. */
  --gray-med:#b8babb;
  --gray-dark:#323233;
  --gray-light:#e6e6e6;
  --on-dark:#f9f9f9;          /* text on the black */
  --on-dark-muted:#c9cacb;    /* labels on the black */

  --rule:rgba(29,29,30,.15);
  --rule-strong:rgba(29,29,30,.32);
  --rule-invert:rgba(249,249,249,.22);

  /* type — the real brand faces. Termina and Proxima Nova come from the live
     site's own Adobe Fonts kit jrb3dte; Lora is a Google font and is not in the
     kit. Archivo/Figtree remain as fallbacks only, in case the kit fails to load.

     TERMINA ONLY SHIPS 500 AND 600 in this kit, and the live Webflow stylesheet
     uses exactly those two and never 700. Asking for 700/800 gets a synthesized
     faux-bold, so every Termina rule here is capped at 600.

     Buttons are deliberately NOT Termina — Proxima Nova, per Liz, 2026-09-03.
     The live Webflow site sets .button in termina; this is a change from it. */
  --display:"termina","Archivo",system-ui,sans-serif;   /* 500, 600 only */
  --sans:"proxima-nova","Figtree",system-ui,sans-serif; /* 400, 700 (+italics) */
  --serif:"Lora",Georgia,serif;

  --shell:1280px;
  --gut:clamp(20px,4vw,64px);
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;
     /* Liz, 2026-09-11: a link that jumps to a section of the same page eases
        there instead of cutting. Every in-page link on the site goes through
        this - the issue pages' Front rows, "Jump to contents", /order's
        "Read Reviews". Honoured only where the reader has not asked for less
        motion. */
     scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
/* so the target heading lands a little below the top edge, not flush to it */
[id]{scroll-margin-top:clamp(18px,3vw,44px)}
body{
  margin:0;background:var(--paper);color:var(--ink);
  font-family:var(--sans);font-size:17px;line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block;height:auto}
a{color:inherit}
/* a heading that is also a link: no underline, takes the accent on hover.
   Used by the issue titles on /issues (Liz, 2026-09-11). */
.plainlink{text-decoration:none}
.plainlink:hover{color:var(--accent)}
:focus-visible{outline:2px solid var(--green);outline-offset:3px}

/* ---------- furniture: the print-magazine layer ------------------------- */

.shell{max-width:var(--shell);margin:0 auto;padding:0 var(--gut)}

/* small caps label. Encodes real metadata, never decoration. */
.eyebrow{
  font-family:var(--display);font-size:12px;font-weight:600;
  letter-spacing:.18em;text-transform:uppercase;
  color:var(--ink);margin:0;
}
.eyebrow--invert{color:var(--on-dark-muted)}

.rule{border:0;border-top:1px solid var(--rule);margin:0}
.rule--strong{border-top-color:var(--rule-strong)}
.rule--invert{border-top-color:var(--rule-invert)}

h1,h2,h3,h4{font-family:var(--display);font-weight:600;letter-spacing:-.02em;margin:0}
h1{font-size:clamp(34px,5.4vw,68px);line-height:1.02}
h2{font-size:clamp(24px,2.6vw,34px);line-height:1.1}
h3{font-size:clamp(19px,1.7vw,23px);line-height:1.2;letter-spacing:-.01em}
p{margin:0 0 1em}

.dek{font-family:var(--serif);font-size:clamp(18px,1.7vw,22px);line-height:1.5;color:rgba(29,29,30,.78)}
.dek--invert{color:rgba(249,249,249,.8)}
.dek--sm{font-size:clamp(17px,1.4vw,19px)}
.fineprint{font-size:15px;color:var(--gray-med-dark)}
.fineprint--note{margin:18px 0 0;max-width:52ch}
.fineprint a{color:var(--ink);border-bottom:1px solid var(--rule-strong);text-decoration:none}
.fineprint a:hover{color:var(--accent);border-bottom-color:var(--accent)}

/* section band. Padding lives here only, so nothing cancels out. */
.band{padding:clamp(52px,7vw,96px) 0}
.band--tight{padding:clamp(36px,4.5vw,56px) 0}
.band--ink{background:var(--ink);color:var(--on-dark)}
/* #43 / #44 (2026-09-04): light type on the black needs more air than ink on
   paper. Headings lose most of their negative tracking, lines open up, and a
   heading gets a clear gap before its paragraph. */
.band--ink h2,.band--ink h3{letter-spacing:-.005em;line-height:1.2}
.band--ink h2{margin-bottom:18px}
.band--ink .dek{line-height:1.6;letter-spacing:.004em}
.band--ink p{letter-spacing:.004em}

.band--paper2{background:var(--paper-2)}
/* A section separated by a hairline instead of by its own full-bleed colour.
   The page ran twelve colour switches down its length, one per idea, which is
   what made it read as a stack of blocks rather than as one page. */
.band--rule{border-top:1px solid var(--rule)}

.mw-30{max-width:30ch}
.mw-34{max-width:34ch}
.mt-44{margin-top:clamp(30px,3.6vw,44px)}

.band-head{display:flex;align-items:baseline;justify-content:space-between;gap:24px;flex-wrap:wrap;margin-bottom:28px}
.band-head h2{max-width:22ch}

/* ---------- buttons ---------------------------------------------------- */

.btn{
  display:inline-flex;align-items:center;gap:.6em;
  font-family:var(--sans);font-size:13.5px;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase;text-decoration:none;
  padding:15px 26px;border:1px solid var(--ink);background:var(--ink);color:var(--on-dark);
  transition:background .18s ease,color .18s ease,transform .18s ease;
}
.btn:hover{background:var(--ink-lift);border-color:var(--ink-lift);transform:translateY(-1px)}
.btn--go{background:var(--green);border-color:var(--green);color:#08240f}
.btn--go:hover{background:#2c9350;border-color:#2c9350;color:#fff}
.btn--ghost{background:transparent;color:var(--ink)}
.btn--ghost:hover{background:var(--ink);color:var(--on-dark)}
.btn--ghost-invert{background:transparent;color:var(--on-dark);border-color:var(--rule-invert)}
.btn--ghost-invert:hover{background:var(--on-dark);color:var(--ink);border-color:var(--on-dark)}
.btn-row{display:flex;gap:12px;flex-wrap:wrap;margin-top:28px}
/* One primary action carries the box; everything beside it is a link.
   Three identically outlined rectangles in a row read as a button kit, and
   they also flatten the hierarchy — "Digital PDF" was as loud as "Read online". */
.btn-row--lead{align-items:center;gap:12px clamp(18px,2.4vw,30px)}
.btn-row--lead .also{display:flex;flex-wrap:wrap;gap:8px clamp(16px,2vw,24px)}
.btn-row--links{margin-top:22px}
.btn-row--lead .also a{
  font-family:var(--sans);font-size:13px;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;text-decoration:none;color:var(--ink);
  border-bottom:1px solid var(--rule-strong);padding-bottom:3px;
}
.btn-row--lead .also a:hover{color:var(--accent);border-bottom-color:var(--accent)}
.band--ink .btn-row--lead .also a{
  color:var(--on-dark);border-bottom-color:var(--rule-invert)
}
.band--ink .btn-row--lead .also a:hover{
  color:#fff;border-bottom-color:var(--green)
}

.tlink{
  font-family:var(--display);font-size:12px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;text-decoration:none;border-bottom:1px solid currentColor;
  padding-bottom:3px;white-space:nowrap;
}
.tlink:hover{color:var(--accent)}
.band--ink .tlink:hover{color:var(--accent)}

/* ---------- masthead --------------------------------------------------- */

.masthead{background:var(--ink);color:var(--on-dark)}
/* #21 (2026-09-04): article pages use the same masthead, on paper. Same
   markup, the ink wordmark, and the nav in ink. */
.masthead--light{background:var(--paper);color:var(--ink);border-bottom:1px solid var(--rule)}
.masthead--light .nav a{color:var(--ink);opacity:.78}
.masthead--light .nav a:hover,.masthead--light .nav a[aria-current]{opacity:1}
.masthead--light .navtoggle{border-color:var(--rule-strong);color:var(--ink)}
.masthead--light .navtoggle:hover{border-color:var(--ink)}
.masthead--light .mobilenav{background:var(--ink);color:var(--on-dark);border-top-color:var(--rule-invert)}
/* longhand only: a `padding` shorthand here would cancel .shell's
   horizontal gutter, since both are single-class selectors. */
/* 2026-09-11 (Liz): the bar was 16px top and bottom, which read as cramped
   against a 200-260px wordmark. Opened to 28px, and to 22px on a phone where
   the lockup is smaller and the screen is shorter. */
.masthead-bar{display:flex;align-items:center;justify-content:space-between;gap:24px;padding-top:28px;padding-bottom:28px}
.masthead-bar img{width:clamp(200px,20vw,260px)}

/* The publisher line used to be baked into the logo SVG, where it came out
   about 7px tall at the size the masthead shows the lockup and went to mush
   at 1x. It is live type now, over a wordmark-only SVG.

   The SVG's own line is Termina 600. At 9.5px with .07em tracking the HTML
   sets to 250px — the same width as the wordmark under it — so the two still
   read as one lockup. Keep those two values in step: change the size and the
   tracking has to move with it or the edges stop lining up. */
.brand{display:block;text-decoration:none;color:inherit}
/* #1 (2026-09-04): the 'From Make The World Better Magazine' eyebrow is gone
   from the masthead. The lockup is the wordmark alone, as in the footer. The
   rule stays for any page that still carries the span. */
.brand-eyebrow{
  display:none;font-family:var(--display);font-weight:600;
  font-size:9.5px;letter-spacing:.07em;line-height:1;white-space:nowrap;
  color:var(--on-dark-muted);margin-bottom:9px;
}
.nav{display:flex;align-items:center;gap:clamp(16px,2.2vw,34px)}
.nav a{
  font-family:var(--display);font-size:12.5px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;text-decoration:none;color:var(--on-dark);opacity:.82;
  padding:6px 0;border-bottom:1px solid transparent;
}
.nav a:hover,.nav a[aria-current]{opacity:1;border-bottom-color:var(--green)}
.nav .lang{opacity:.55;font-size:10.5px}

/* thin standing line: what issue you are in, always visible */
.issue-strip{
  background:var(--ink);color:var(--gray-light);
  font-family:var(--display);font-size:11.5px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;
}
.issue-strip .shell{display:flex;justify-content:space-between;gap:16px;padding-top:9px;padding-bottom:9px;flex-wrap:wrap}
.issue-strip a{text-decoration:none;border-bottom:1px solid rgba(249,249,249,.4)}
.issue-strip a:hover{border-bottom-color:var(--green);color:#fff}

/* ---------- hero ------------------------------------------------------- */

.hero{background:var(--paper-2);padding:clamp(44px,6vw,80px) 0 clamp(48px,6vw,88px)}
.hero-grid{display:grid;grid-template-columns:minmax(0,.85fr) minmax(0,1.15fr);gap:clamp(32px,6vw,88px);align-items:center}
.hero-grid--textfirst{grid-template-columns:minmax(0,1.12fr) minmax(0,.88fr)}
.hero-grid--textfirst .hero-copy h1{max-width:24ch}
.hero-copy h1{margin:14px 0 20px;max-width:20ch}

/* the cover, treated as a physical object */
.cover{
  position:relative;display:block;perspective:1400px;
  background:none;border:0;padding:0;
}
/* #3 and #34 (2026-09-04): shadow cut to a quiet lift, and the 6deg tilt is
   gone. The tilt rotated the image but not the sheen overlay on top of it, so
   on hover a hairline of the overlay showed past the image's corner. */
.cover img{
  width:100%;box-shadow:0 6px 18px rgba(29,29,30,.12);
  transform:none;transform-origin:center;
  transition:transform .4s cubic-bezier(.2,.7,.2,1),box-shadow .4s ease;
}
.cover:hover img{transform:translateY(-4px);box-shadow:0 12px 28px rgba(29,29,30,.16)}
.cover::after{display:none}

/* ---------- hover flip-through ------------------------------------------
   The cover opens into a real two-page spread and the actual pages of Issue 02
   turn about the spine, front face to back face, as in the flipbook at
   read.circulareconomymag.com — same component as the one on
   sparxpg.com/make-the-world-better, including its --overlap modifier below.

   The geometry problem this solves: a page turning about the cover's left edge
   needs a page-width of clear space to its left, which is exactly where the hero
   copy lives. So the book is twice the cover's width with the spine at its
   centre, and it opens by scaling DOWN to --open-scale. Closed, the right half
   sits precisely over the cover's footprint; open, the whole spread is centred on
   that same footprint and overflows only into the grid gutter. .flipbox reserves
   the closed cover's height so the band never resizes mid-hover.

   Page images are hydrated from data-src on first hover, so the hero still ships
   one cover image. No JS, or reduced motion: the closed cover, unchanged. */
.cover--flip{--open-scale:.58;transform-style:preserve-3d;perspective:2400px}
.cover--flip img{width:100%;height:auto;display:block;transform:none;transition:none;box-shadow:none}
.cover--flip .flipbox{position:relative;aspect-ratio:1200/1558}
.cover--flip .book{
  position:absolute;top:0;left:-100%;width:200%;height:100%;
  transform-style:preserve-3d;transform-origin:50% 0;
  transform:none;
  transition:transform .62s cubic-bezier(.2,.7,.2,1);
  pointer-events:none;
  /* .book's own box is 200% wide, left:-100% — twice the footprint of the
     visible closed cover, even before it opens. Without this, that whole
     phantom half counts as part of the anchor's hoverable area, so hovering
     the empty space (or the hero copy) beside the cover opens it. root's
     hoverable area falls back to .flipbox, which matches the visible cover. */
}
/* translateX(25%) is half the book's width, which re-centres the open spread on
   the closed cover's footprint instead of on the spine — the fallback for
   narrow/stacked layouts, where .cover--flip--overlap below is switched off.
   .book's transform-origin is 50% 0 (top), not 50% 50%, so this scale-down
   shrinks toward the closed cover's own top edge instead of its vertical
   centre — otherwise the top of the open spread drifts down by half the
   shrink and leaves a band of blank space above it (mobile, 2026-09-11). */
.cover--flip.is-open .book{transform:translateX(25%) scale(var(--open-scale))}

/* ---------- hover flip-through: stay-in-place variant -------------------
   --overlap cancels the re-centre-and-shrink above: the book's right half
   (the closed cover) never moves, and the left half — previously hidden at
   left:-100% — swings into view at its real, undiminished size, laid over
   the hero copy instead of shrinking to fit next to it. z-index lifts it
   above that copy while open. Gated to the two-column layout: below that,
   the cover sits flush against the page's left edge with no clear space to
   open into, so it keeps the scale-down fallback above instead. */
.cover--flip--overlap{z-index:5}
.cover--flip--overlap.is-open{z-index:6}
@media (min-width:1001px){
  .cover--flip--overlap.is-open .book{transform:none}
}

.cover--flip .leaf{
  position:absolute;top:0;right:0;width:50%;height:100%;
  transform-origin:left center;transform-style:preserve-3d;
  transition:transform .74s cubic-bezier(.42,.02,.28,1);
}
/* the closed stack, in CSS rather than from JS: without this the leaves sit at
   the same Z, 3D sorting picks the last one in the DOM, and a visitor with JS
   off sees page 9 where the cover should be */
.cover--flip .leaf:nth-child(1){transform:translateZ(0)}
.cover--flip .leaf:nth-child(2){transform:translateZ(-1.2px)}
.cover--flip .leaf:nth-child(3){transform:translateZ(-2.4px)}
.cover--flip .leaf:nth-child(4){transform:translateZ(-3.6px)}
.cover--flip .leaf:nth-child(5){transform:translateZ(-4.8px)}
.cover--flip .face{
  position:absolute;inset:0;backface-visibility:hidden;overflow:hidden;
  background:var(--paper);
  box-shadow:0 6px 18px rgba(29,29,30,.12);
}
/* #4 (2026-09-04): the page images are 560x727 and the face is 1200:1558; the
   two ratios round differently at most widths and left a hairline of --paper
   above and below every page. Fill the face and let the image crop. */
.cover--flip .face img{width:100%;height:100%;object-fit:cover}
.cover--flip .face--back{transform:rotateY(180deg)}
.cover--flip .face::after{        /* gutter shadow, deepest at the spine */
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,rgba(29,29,30,.26),rgba(29,29,30,0) 20%);
}
.cover--flip .face--back::after{
  background:linear-gradient(270deg,rgba(29,29,30,.26),rgba(29,29,30,0) 20%);
}
.cover--flip:hover .book,.cover--flip:focus-visible .book{transition-duration:.62s}
.cover--flip::after{transition:opacity .4s ease}
.cover--flip.is-open::after{opacity:0}     /* the flat sheen only suits the closed cover */

.cover-hint{
  position:absolute;left:0;bottom:-30px;
  font-family:var(--display);font-size:11.5px;font-weight:600;
  letter-spacing:.16em;text-transform:uppercase;color:var(--gray-med-dark);
  opacity:0;transform:translateY(-4px);transition:opacity .3s ease,transform .3s ease;
}
.cover--flip:hover .cover-hint,.cover--flip:focus-visible .cover-hint{opacity:1;transform:translateY(0)}
/* No hover to reveal the hint on a touchscreen, and flip.js makes the cover
   itself tap-to-replay there - so the hint needs to just sit visible,
   otherwise nothing on the page suggests tapping it does anything at all. */
@media (hover:none){.cover-hint{opacity:1;transform:none}}

/* ---------- article cards --------------------------------------------- */

/* gap:1px over a ruled background is the hairline-table trick: it welds the
   cards into one bordered grid. Real gaps instead, so each card is a card and
   the paper runs behind all of them. */
.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(26px,3.2vw,44px)}
.cards--2{grid-template-columns:repeat(2,minmax(0,1fr))}
.cards--4{grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(20px,2.4vw,32px)}
@media (max-width:1000px){.cards--4{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.cards--4{grid-template-columns:1fr}}
.cards--4 h3{font-size:clamp(17px,1.4vw,19px)}
.card{padding:0;display:flex;flex-direction:column;text-decoration:none}
.card-img{aspect-ratio:16/10;overflow:hidden;background:var(--gray-light)}
.card-img img{width:100%;height:100%;object-fit:cover;transition:transform .55s cubic-bezier(.2,.7,.2,1)}
.card:hover .card-img img{transform:scale(1.04)}
.card-body{padding:18px 0 0;display:flex;flex-direction:column;flex:1}
.card-top{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin-bottom:12px}
.card h3{margin-bottom:9px}
.card:hover h3{color:var(--accent)}
/* Deks on these cards come from the live site and run from 65 to 592
   characters, which left one card three lines deep and its neighbour ten, so a
   row of three read as broken rather than as a set. Clamped to three lines:
   the cards now agree, and the full standfirst is on the article itself. */
.card p{font-family:var(--serif);font-size:15.5px;line-height:1.5;color:rgba(29,29,30,.7);margin:0;
        display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.card-foot{margin-top:auto;padding-top:14px;font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--gray-med-dark)}

/* the folio: an article's position in its printed issue. Order is real
   information in a magazine, so it is worth showing. */
.folio{
  font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.1em;
  color:var(--ink);white-space:nowrap;
}
.folio--invert{color:var(--on-dark-muted)}
.tag{font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.15em;text-transform:uppercase;color:var(--gray-med-dark)}
.fr{font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.1em;color:var(--blue);border:1px solid var(--blue);padding:2px 5px}

/* ---------- issue archive strip --------------------------------------- */

.shelf{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(18px,2.6vw,34px)}
.shelf a{text-decoration:none;display:block}
.shelf img{box-shadow:0 6px 18px rgba(29,29,30,.12);transition:transform .35s cubic-bezier(.2,.7,.2,1),box-shadow .35s ease}
.shelf a:hover img{transform:translateY(-6px);box-shadow:0 12px 28px rgba(29,29,30,.16)}
.shelf-meta{margin-top:14px;padding-top:12px;border-top:1px solid var(--rule)}
.shelf-meta strong{display:block;font-family:var(--display);font-size:15px;margin-top:5px;letter-spacing:-.01em}
.shelf-soon{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;aspect-ratio:3/4;border:1px dashed var(--rule-strong);color:var(--gray-med-dark);text-align:center;padding:18px;font-family:var(--display);font-size:11.5px;font-weight:600;letter-spacing:.13em;text-transform:uppercase;line-height:1.65;overflow-wrap:anywhere}
.shelf-soon strong{display:block;font-size:15px;letter-spacing:-.01em;text-transform:none;color:var(--ink);line-height:1.25}
.shelf-soon--solid{border-style:solid;background:var(--ink);border-color:var(--ink);color:var(--gray-light)}
.shelf-soon--solid strong{color:#fff}
.shelf-soon .arrow{font-size:20px;letter-spacing:0;color:var(--green)}

/* ---------- offers (buy) ---------------------------------------------- */

.offers{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(30px,4.5vw,64px)}
/* The recommended tier is marked by a green rule, not by filling its cell:
   once the cells lose their borders a lone filled rectangle reads as a stray
   panel rather than as emphasis. */
.offer{padding:20px 0 0;display:flex;flex-direction:column;border-top:1px solid var(--rule-invert)}
.offer h3{margin:0 0 10px}
.offer p{font-family:var(--serif);font-size:16px;line-height:1.55;color:rgba(249,249,249,.74)}
/* #15 (2026-09-04): the tiers band is on paper now. Same components, ink values. */
.offers--light .offer{border-top-color:var(--rule-strong)}
.offers--light .offer p{color:rgba(29,29,30,.72)}
.offers--light .offer-flag{color:var(--gray-med-dark)}
.offers--light .offer--feature .offer-flag{color:#1f7d40}
.offers--light .tier-list dt{color:var(--gray-med-dark)}
.offers--light .tier-list li{color:rgba(29,29,30,.84)}
.offers--light .tier-list li::before{background:var(--gray-med-dark)}
.offers--light .tier-list em{color:var(--gray-med-dark)}
.offer .price{font-family:var(--display);font-size:32px;font-weight:600;letter-spacing:-.02em;margin:6px 0 4px}
.offer .price small{font-size:13px;font-weight:600;letter-spacing:.1em;opacity:.6;margin-left:6px}
.offer .btn{margin-top:auto;align-self:flex-start}
.offer--feature{border-top:2px solid var(--green)}
.offer-flag{font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.16em;
            text-transform:uppercase;color:var(--on-dark-muted);margin:-4px 0 12px}
.offer--feature .offer-flag{color:var(--green)}

/* what a tier includes, grouped as the media kit groups it. A definition list
   because that is what it is: four category labels, each with its inclusions. */
.tier-list{margin:18px 0 0;display:grid;gap:16px}
.tier-list dt{
  font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.15em;
  text-transform:uppercase;color:var(--on-dark-muted);
}
.tier-list dd{margin:6px 0 0}
.tier-list ul{margin:0;padding:0;list-style:none;display:grid;gap:7px}
.tier-list li{
  position:relative;padding-left:16px;font-size:15.5px;line-height:1.55;
  color:rgba(249,249,249,.82);
}
.tier-list li::before{
  content:"";position:absolute;left:0;top:.62em;width:5px;height:5px;
  background:var(--on-dark-muted);
}
.tier-list em{font-style:normal;color:rgba(249,249,249,.6)}

/* ---------- partner band ---------------------------------------------- */

.two-col{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(30px,4.5vw,68px)}
.two-col > div{border-top:1px solid var(--rule-strong);padding:20px 0 0}
.two-col--invert > div{border-top-color:var(--rule-invert)}

.issue-row{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);gap:clamp(28px,5vw,72px);align-items:center}
.issue-row .cover{max-width:400px}
/* previous-issue block: clearly secondary to the hero, and the title travels
   with its own dek and buttons instead of being stranded in the band head */
.issue-row--past{align-items:start;grid-template-columns:minmax(0,.5fr) minmax(0,1fr)}
.issue-row--past .cover{max-width:270px}
.issue-row--past h2{margin:0 0 14px}
@media (max-width:1000px){.issue-row--past{grid-template-columns:1fr}}
@media (max-width:1000px){.issue-row{grid-template-columns:1fr;gap:30px}.issue-row .cover{max-width:320px}}

/* ---------- table of contents (the signature) ------------------------ */
/* #32 (2026-09-04): print page numbers are gone from the web contents, so the
   first column collapses. Section names still head each group. */
.toc.toc--nonum a,.toc.toc--nonum .row{grid-template-columns:1fr auto}
.toc-sec--plain{margin:44px 0 14px}
.toc-sec--plain .eyebrow{font-size:12px}
/* 2026-09-11 (Liz): every issue names its sections the same way - Front, Theme
   Spreads, Features, Also in this issue - so the section eyebrow can no longer
   carry the issue's own theme-spread title. It sits under the eyebrow instead. */
.toc-sec-sub{font-family:var(--display);font-size:16px;font-weight:600;letter-spacing:-.01em;
             color:var(--gray-med-dark);margin:7px 0 0}

.toc{margin:0;padding:0;list-style:none;border-top:1px solid var(--rule-strong)}
.toc li{border-bottom:1px solid var(--rule)}
.toc a,.toc .row{display:grid;grid-template-columns:58px 1fr auto;gap:clamp(14px,2.4vw,30px);align-items:baseline;padding:20px 4px;text-decoration:none;transition:background .16s ease,padding-left .16s ease}
.toc a:hover{background:#fff;padding-left:12px}
.toc .num{font-family:var(--display);font-size:12.5px;font-weight:600;letter-spacing:.06em;color:var(--ink);padding-top:4px}
.toc .ttl{font-family:var(--display);font-size:clamp(17px,1.6vw,21px);font-weight:600;letter-spacing:-.01em;line-height:1.25}
.toc .sub{display:block;font-family:var(--serif);font-weight:400;letter-spacing:0;font-size:15.5px;line-height:1.45;color:rgba(29,29,30,.68);margin-top:6px;max-width:62ch}
.toc .by{display:block;font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--gray-med-dark);margin-top:9px}
.toc .rt{font-family:var(--display);font-size:11.5px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--gray-med-dark);white-space:nowrap;padding-top:5px}
.toc-sec{display:flex;align-items:center;gap:16px;margin:44px 0 14px}
.toc-sec:first-of-type{margin-top:0}
.toc-sec .rule{flex:1}

/* ---------- contributors (issue pages, #33 2026-09-04) ----------------
   The printed masthead, as a web list: the interviewees, the guest author,
   and the team. Names in the display face, roles beneath in the serif. */
.contrib{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(22px,3vw,40px) clamp(24px,3.4vw,52px);margin-top:clamp(24px,3vw,36px)}
.contrib > div{border-top:1px solid var(--rule);padding-top:16px}
.contrib .org{font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--gray-med-dark);margin:0 0 8px}
.contrib .who{font-family:var(--display);font-size:16px;font-weight:600;letter-spacing:-.01em;line-height:1.3;margin:0}
.contrib .role{font-family:var(--serif);font-size:15.5px;line-height:1.5;color:rgba(29,29,30,.72);margin:4px 0 0}
.contrib-team{margin-top:clamp(30px,4vw,48px);padding-top:22px;border-top:1px solid var(--rule-strong);display:flex;flex-wrap:wrap;gap:16px clamp(28px,4vw,56px)}
.contrib-team div{min-width:150px}
.contrib-team .org{font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--gray-med-dark);margin:0 0 6px}
.contrib-team .who{font-family:var(--sans);font-size:16px;margin:0;line-height:1.45}
@media (max-width:900px){.contrib{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:560px){.contrib{grid-template-columns:1fr}}

/* ---------- article page ---------------------------------------------- */

.art-hero{background:var(--paper-2);padding:clamp(34px,4.5vw,58px) 0 0}
.art-head{max-width:74ch}
.art-head h1{margin:16px 0 18px}
.art-byline{display:flex;gap:22px;flex-wrap:wrap;align-items:center;margin-top:26px;padding:16px 0;border-top:1px solid var(--rule);border-bottom:1px solid var(--rule);font-family:var(--display);font-size:10.5px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--gray-med-dark)}
.art-figure{margin:0}
.art-figure img{width:100%}
.art-figure figcaption{font-family:var(--sans);font-size:15px;line-height:1.5;color:var(--gray-med-dark);padding:12px 0 0;max-width:70ch}

.prose{max-width:68ch;margin:0 auto;font-family:var(--serif);font-size:19px;line-height:1.72}
.prose p{margin:0 0 1.35em}
/* standfirst: the opening paragraph reads larger and in the brand ink.
   Chosen over a drop cap, which collapses to a bare stem whenever an
   article opens on I, J or l — and roughly a third of these do. */
.prose > p:first-of-type{
  font-size:1.18em;line-height:1.55;color:var(--ink);
  padding-bottom:.4em;margin-bottom:1.5em;border-bottom:1px solid var(--rule);
}
/* A body split around full-width figures becomes several .prose blocks, and
   every one of them would otherwise take the standfirst rule above on its own
   first paragraph — larger and ruled — three or four times down the page.
   Only the block that actually opens the article carries it. */
.prose--cont > p:first-of-type{
  font-size:1em;line-height:1.72;color:inherit;
  padding-bottom:0;margin-bottom:1.35em;border-bottom:0;
}
.prose h2{font-size:clamp(20px,2vw,26px);margin:2.1em 0 .7em;color:var(--ink)}
/* First heading in a continuation block sits right under a figure, so it does
   not need the 2.1em of air the rule above gives a heading mid-prose. */
.prose--cont > h2:first-child{margin-top:0}
.prose blockquote{
  margin:2em 0;padding:0 0 0 26px;border-left:2px solid var(--green);
  font-size:24px;line-height:1.4;font-style:normal;color:var(--ink);
}
.prose blockquote p:last-child{margin:0}
.prose .pull-note{font-family:var(--sans);font-size:15.5px;color:var(--gray-med-dark)}
.contact-card{border-left:2px solid var(--green);padding:2px 0 2px 22px;margin:44px 0 0;font-family:var(--sans);font-size:15px}
.contact-card ul{margin:14px 0 0;padding:0;list-style:none;display:grid;gap:8px}
.contact-card a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--rule-strong)}
.contact-card a:hover{color:var(--accent);border-bottom-color:var(--accent)}

/* print-copy inline CTA inside the read */
.inline-buy{background:var(--ink);color:var(--on-dark);padding:30px 30px 34px;margin:52px 0 0;display:grid;grid-template-columns:1fr auto;gap:24px;align-items:center}
.inline-buy h3{margin:8px 0 0;max-width:26ch}
.inline-buy .btn{white-space:nowrap}
/* The 52px top margin above separated this box from the last contents row,
   back when it sat at the foot of the list. It now has a band of its own on
   every issue page, where that margin only makes the band lopsided - 148px of
   paper above the box against 94px below it (Ken, 2026-09-11). */
.shell > .inline-buy:first-child{margin-top:0}

/* ---------- footer ---------------------------------------------------- */

.foot{background:var(--ink);color:var(--on-dark);padding:clamp(46px,5.5vw,72px) 0 30px}
.foot-grid{display:grid;grid-template-columns:1.5fr 1fr 1fr 1fr;align-items:start;gap:clamp(24px,3.4vw,48px)}
/* #a11y (2026-09-12): was h4. Nothing on any page reaches h4 before the
   footer, so it was always a skipped level (h2 or h3 straight to h4). h3
   never skips, whatever heading last appeared above the footer. */
.foot h3{font-family:var(--display);font-size:11.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--on-dark-muted);margin-bottom:16px}
.foot ul{margin:0;padding:0;list-style:none;display:grid;gap:11px}
.foot a{color:rgba(249,249,249,.82);text-decoration:none;font-size:15px}
.foot a:hover{color:#fff;text-decoration:underline}
/* #19 (2026-09-04): larger wordmark, and #18 removed the tagline under it.
   Tagline reinstated 2026-09-11 per the site copy doc. */
.foot img{width:286px;max-width:100%;margin-bottom:14px}
.foot-tagline{margin:0 0 22px;max-width:34ch;font-size:15px;line-height:1.5;color:rgba(249,249,249,.72)}
.foot-note{margin-top:38px;padding-top:22px;border-top:1px solid var(--rule-invert);display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap;font-size:15px;color:rgba(249,249,249,.62)}
/* #35: the publisher link inherited .foot a's 15px while the line around it
   was 13.5px, so one word in the sentence sat a size larger. Inherit. */
/* #a11y (2026-09-12): opacity alone isn't a visible cue that this is a link,
   distinct from the plain text around it - it needs its own border, the same
   way every other in-sentence link on the site already has one. */
.foot-note a{font-size:inherit;color:rgba(249,249,249,.85);text-decoration:none;
            border-bottom:1px solid rgba(249,249,249,.4)}
.foot-note a:hover{color:#fff;border-bottom-color:#fff}

/* newsletter: #20 (2026-09-04) moved out of the footer column into its own
   band directly above the footer, on every page that has a footer. */
.newsband{background:var(--paper-2);border-top:1px solid var(--rule);padding:clamp(40px,5vw,64px) 0}
.newsband .shell{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,.9fr);gap:clamp(24px,4vw,64px);align-items:center}
.newsband h2{font-size:clamp(22px,2.2vw,30px);margin:0 0 10px}
.newsband .lede{font-family:var(--serif);font-size:17px;line-height:1.55;color:rgba(29,29,30,.78);margin:0;max-width:48ch}
.newsband .signup{margin-top:0;max-width:none}
.newsband .signup input{border-bottom-color:var(--rule-strong);color:var(--ink)}
.newsband .signup input::placeholder{color:var(--gray-med-dark)}
.newsband .fineprint{margin:10px 0 0;font-size:15px}
@media (max-width:820px){.newsband .shell{grid-template-columns:1fr}}
.signup{display:grid;grid-template-columns:1fr auto;gap:14px;align-items:end;margin-top:18px;max-width:420px}
/* the field sits in its own div so the label can be hidden without breaking
   the two-column grid; the status line spans both columns under it */
.signup > div:first-child{min-width:0}
.signup .formstatus,.signup .hp{grid-column:1 / -1}
.signup .formstatus{margin:0;color:var(--on-dark)}
.signup .formstatus--bad{color:#ffb4ab}
.signup .formstatus--ok{color:#8fe0ab}
.newsband .signup .formstatus{color:var(--ink)}
.newsband .signup .formstatus--bad{color:#b3261e}
.newsband .signup .formstatus--ok{color:#1f7a3f}
.signup input{width:100%}
/* underline, not an input box: on a dark ground a bordered field plus a solid
   button is two more rectangles for one small job */
.signup input{
  font-family:var(--sans);font-size:15px;padding:11px 2px;
  border:0;border-bottom:1px solid var(--rule-invert);border-radius:0;
  background:none;color:var(--on-dark);
}
.signup input::placeholder{color:rgba(249,249,249,.5)}
.signup input:focus{border-bottom-color:var(--green);outline:none}
.signup .btn{padding:12px 22px}

/* ---------- responsive ------------------------------------------------ */

@media (max-width:1180px){.cover--flip{--open-scale:.54}}
@media (max-width:1000px){
  .hero-grid{grid-template-columns:1fr;gap:36px}
  /* single column: .5 makes the open spread exactly as wide as the closed cover,
     so it cannot run off the left edge whatever the column alignment */
  .cover--flip{--open-scale:.5}
  .cover{max-width:340px}
  .cover img{transform:none}
  .cards,.cards--2{grid-template-columns:repeat(2,minmax(0,1fr))}
  .shelf{grid-template-columns:repeat(2,minmax(0,1fr))}
  .offers{grid-template-columns:1fr}
  .foot-grid{grid-template-columns:1fr 1fr}
  .nav{display:none}
}
@media (max-width:640px){
  body{font-size:16px}
  .cards,.cards--2,.two-col{grid-template-columns:1fr}
  .logorow{grid-template-columns:1fr}
  .toc a,.toc .row{grid-template-columns:42px 1fr;padding:18px 2px}
  .toc .rt{display:none}
  .inline-buy{grid-template-columns:1fr}
  .prose{font-size:17.5px}
  .foot-grid{grid-template-columns:1fr}
  .signup{grid-template-columns:1fr}
}

@media (prefers-reduced-motion:reduce){
  *{transition-duration:.01ms !important;animation-duration:.01ms !important}
  .cover img{transform:none}
  /* the book never opens and no leaf ever turns */
  .cover--flip .book,.cover--flip.is-open .book{transform:none}
  .cover--flip .leaf.is-turned{transform:none !important}
  .cover-hint{opacity:1;transform:none}
}

/* ==========================================================================
   Sketch bands — added 2026-08-18 from CE Sketch.png
   ========================================================================== */

/* ---------- ad slot: first-class inventory, directly below the nav ------ */
.adslot{background:var(--paper);border-bottom:1px solid var(--rule)}
.adslot .shell{padding-top:0;padding-bottom:0}
/* A dashed rectangle labelled with its own dimensions is how an unsold slot
   looks in a mockup, not on a magazine's site. The label alone marks it as
   advertising; the slot is held open by min-height, not by a border. */
.adslot-inner{
  display:flex;align-items:center;justify-content:space-between;gap:20px 40px;flex-wrap:wrap;
  padding:20px 0 22px;min-height:104px;
}
.adslot-label{font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.2em;text-transform:uppercase;color:var(--gray-med-dark)}
.adslot-inner strong{display:block;font-family:var(--display);font-size:clamp(17px,1.8vw,22px);letter-spacing:-.01em;margin-top:6px;max-width:34ch}
.adslot-inner p{font-size:15px;color:var(--gray-med-dark);margin:6px 0 0;max-width:46ch}

/* An actual creative (728x90 leaderboard), not the copy mock above. The image
   carries its own message and CTA, so this wrapper is just the disclosure
   label plus a centered, responsive frame for it (Ken, 2026-09-11: Purpose-
   Driven Events house ad, example inventory). */
.adslot-creative{padding:16px 0 20px;display:flex;flex-direction:column;align-items:center;gap:8px}
.adslot-creative-link{display:block;line-height:0}
.adslot-creative-link img{width:100%;max-width:970px;height:auto;display:block}

/* ---------- current-issue strip: text-forward, keeps articles linked ---- */
.strip{border-top:1px solid var(--rule-strong);border-bottom:1px solid var(--rule)}
.strip-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:0 clamp(20px,3vw,44px);margin:0;padding:0;list-style:none}
.strip-list li{border-bottom:1px solid var(--rule)}
.strip-list a{display:flex;align-items:baseline;gap:14px;padding:15px 4px;text-decoration:none;transition:padding-left .16s ease,background .16s ease}
.strip-list a:hover{background:#fff;padding-left:10px}
.strip-list .n{font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--gray-med-dark);flex:none;width:64px;padding-top:3px}
.strip-list .t{font-family:var(--display);font-size:16px;font-weight:600;letter-spacing:-.01em;line-height:1.3}
.strip-list a:hover .t{color:var(--accent)}

/* ---------- about / editorial mandate ---------------------------------- */
.mandate{display:grid;grid-template-columns:.9fr 1.1fr;gap:clamp(28px,5vw,72px);align-items:start}
.mandate blockquote{margin:0;padding:0 0 0 22px;border-left:2px solid var(--green);font-family:var(--serif);font-size:clamp(19px,2vw,24px);line-height:1.45;color:var(--ink)}
.mandate-body p{font-family:var(--serif);font-size:17.5px;line-height:1.65;color:rgba(29,29,30,.8)}

/* ---------- credits: one section, three groups -------------------------
   These were three consecutive full-bleed bands, each with its own eyebrow and
   its own display-size heading, all answering the same question. One heading
   now, with the three groups separated by rules and introduced by a quiet
   standing head — which is the only place on the page a sub-label carries
   information a reader could not infer (partner vs member vs featured). */
.credits{display:grid;gap:clamp(28px,3.4vw,44px);margin-top:clamp(24px,3vw,36px)}
.credit-group{border-top:1px solid var(--rule);padding-top:20px}
.credit-group > h3{
  font-family:var(--display);font-size:15px;font-weight:600;letter-spacing:.01em;
  color:var(--gray-med-dark);margin:0 0 clamp(18px,2.2vw,26px);
}
/* #40 (2026-09-04): the heading and both remaining groups sit on the centre
   line. The editorial-partners group (#39) is gone, so there is no left-set
   logotile row left to align to. */
.credits--centre .credit-group{text-align:center}
.credits--centre .memrow{justify-content:center}
.credits--centre .credit-group > h3{text-align:center}
.credits-head{text-align:center;max-width:none;margin:0 auto}
.credit-group .memrow,.credit-group .logorow{margin-top:0}

/* ---------- issue sponsors band ----------------------------------------
   The per-issue sponsor thank-you, ported from the live Webflow issue pages
   (copy verbatim). Full colour, unlike the partner marks below: these are
   three paying sponsors, and a sponsor's mark is not ours to flatten.
   Heights are set per-mark rather than uniformly, because Circular Materials
   and CSA Group are horizontal lockups and the RCA mark is a vertical one:
   matched on box height it would read noticeably smaller. ------------------ */
.sponsor-row{display:flex;flex-wrap:wrap;align-items:center;
             gap:clamp(30px,4.2vw,62px);margin-top:clamp(26px,3.2vw,38px)}
.sponsor-row img{display:block;width:auto;height:56px}
.sponsor-row img.sponsor--tall{height:62px}
@media (max-width:600px){
  .sponsor-row{gap:30px}
  .sponsor-row img{height:46px}
  .sponsor-row img.sponsor--tall{height:52px}
}

/* ---------- logo rows: partners and credentials ------------------------ */
.logorow{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,260px));gap:clamp(28px,4vw,60px)}
/* Cells removed. The marks sit on the paper and align on a common baseline,
   with the name and the role beneath — the arrangement a masthead uses. */
.logotile{
  padding:0;display:flex;flex-direction:column;align-items:flex-start;
  justify-content:flex-end;text-align:left;gap:5px;
}
.logotile img{margin-bottom:14px}
.logotile img{display:block;max-width:100%;opacity:.82}
.logotile b{font-family:var(--display);font-size:14px;font-weight:600;letter-spacing:-.01em;line-height:1.25;color:var(--ink)}
.logotile span{font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--gray-med-dark)}
/* .logotile--tk is gone: an empty dashed box reading "TK - open" is a note to
   ourselves, and it was sitting in the partner row on the live prototype. */

/* Memberships row (homepage credentials band). Ported from sparxpg.com's
   `.certs` wall, which is the source of truth for what Sparx can claim.
   Flex, not a grid: a fixed column count leaves the last row hanging whenever
   six does not divide by the columns that fit. Left-aligned rather than centred
   as on sparxpg.com, because every other band on this page sets its content
   flush left under a flush-left heading.
   These stay in FULL COLOUR, unlike the partners/participants marks above.
   Those are 30 third-party logos being flattened into one row, where mixed
   brand systems read as a scrape; these are six credentials, and a
   credential you have de-branded is a weaker claim, not a tidier one. */
.memrow{margin:0;padding:0;list-style:none;
        display:flex;flex-wrap:wrap;justify-content:flex-start;align-items:center;
        gap:clamp(26px,3.2vw,42px) clamp(28px,3.4vw,52px)}
.memrow li{display:flex;align-items:center;justify-content:center}
.memrow a{display:flex;align-items:center;justify-content:center}
/* width/height are set per-image in the HTML from an optical-AREA calculation,
   so a 3.5:1 wordmark does not out-weigh a near-square mark. Do not add
   width:auto here — it would discard those attributes. */
.memrow img{display:block;max-width:100%;height:auto}

/* ---------- past participants: rolling marquee -------------------------
   Chips rather than bare text, so an item sliding out of frame reads as
   intentional. Edge fades are gradient overlays, not mask-image: the mask
   silently no-ops in some engines and left names hard-clipped mid-word. */
.marquee{--fade:var(--paper);position:relative;overflow:hidden;padding:8px 0;margin-top:clamp(22px,3vw,34px)}
.band--paper2 .marquee{--fade:var(--paper-2)}
.marquee::before,.marquee::after{
  content:"";position:absolute;top:0;bottom:0;width:clamp(44px,8vw,130px);
  z-index:2;pointer-events:none;
}
.marquee::before{left:0;background:linear-gradient(90deg,var(--fade) 22%,transparent)}
.marquee::after{right:0;background:linear-gradient(270deg,var(--fade) 22%,transparent)}
.marquee-track{display:flex;width:max-content;gap:12px;animation:roll 96s linear infinite}
.marquee:hover .marquee-track,.marquee:focus-within .marquee-track{animation-play-state:paused}
/* Each item is the organization's own logo, redrawn as a single-ink silhouette
   so 30 marks from 30 brand systems read as one row. Widths come from the HTML
   (area-normalised per logo), which is why a wide wordmark and a square mark
   carry the same visual weight instead of the same height. */
.marquee-track .ml{
  display:inline-flex;align-items:center;justify-content:center;
  padding:0 clamp(20px,2.4vw,40px);min-height:66px;
}
.marquee-track .ml img{display:block;max-width:none;opacity:.72;transition:opacity .2s ease}
.marquee:hover .ml img{opacity:.9}
/* the track holds the list twice; -50% minus half the gap lands seamlessly */
@keyframes roll{from{transform:translateX(0)}to{transform:translateX(calc(-50% - 6px))}}

@media (prefers-reduced-motion:reduce){
  /* becomes a static index: align to the page gutter, and drop the duplicated
     half of the track so each organization is listed once, not twice */
  .marquee{overflow:visible;padding:0;max-width:var(--shell);margin:clamp(22px,3vw,34px) auto 0;padding-left:var(--gut);padding-right:var(--gut)}
  .marquee::before,.marquee::after{display:none}
  .marquee-track{animation:none;flex-wrap:wrap;width:auto;gap:10px}
  .marquee-track span[aria-hidden="true"]{display:none}
}

/* ---------- FAQ: native details/summary, no JS ------------------------- */
.faq{border-top:1px solid var(--rule-strong)}
.faq details{border-bottom:1px solid var(--rule)}
.faq summary{
  display:flex;align-items:center;justify-content:space-between;gap:18px;
  padding:20px 4px;cursor:pointer;list-style:none;
  font-family:var(--display);font-size:clamp(16px,1.5vw,19px);font-weight:600;letter-spacing:-.01em;
  transition:padding-left .16s ease,color .16s ease;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--accent);padding-left:10px}
.faq summary::after{
  content:"";flex:none;width:11px;height:11px;
  border-right:2px solid var(--ink);border-bottom:2px solid var(--ink);
  transform:rotate(45deg) translateY(-3px);transition:transform .22s ease;
}
.faq details[open] summary::after{transform:rotate(-135deg) translateY(-2px)}
.faq .a{padding:0 4px 24px;max-width:74ch;font-family:var(--serif);font-size:17px;line-height:1.65;color:rgba(29,29,30,.8)}
.faq .a p{margin:0 0 .9em}
.faq .a p:last-child{margin:0}
.faq .a a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--rule-strong)}

/* ---------- support-us band -------------------------------------------- */
.support{display:grid;grid-template-columns:.85fr 1.15fr;gap:clamp(28px,5vw,72px);align-items:start}
.support-ways{display:grid;gap:0}
.support-ways > div{padding:18px 0;display:flex;gap:16px;align-items:baseline;border-top:1px solid var(--rule-invert)}
.support-ways > div:last-child{border-bottom:1px solid var(--rule-invert)}
.support-ways .w{display:none;font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--on-dark-muted);flex:none;width:96px;padding-top:3px}
.support-ways strong{display:block;font-family:var(--display);font-size:16px;letter-spacing:-.01em}
.support-ways p{margin:7px 0 0;font-size:15.5px;line-height:1.6;letter-spacing:.005em;color:rgba(249,249,249,.76)}

@media (max-width:1000px){
  .mandate,.support{grid-template-columns:1fr}
  .logorow{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:640px){
  .adslot-inner{min-height:0}
  .support-ways > div{flex-direction:column;gap:6px}
  .support-ways .w{width:auto}
}

/* ==========================================================================
   Mobile navigation — the nav was display:none below 1000px with no
   replacement, leaving small screens with no way to navigate at all.
   ========================================================================== */

.navtoggle{
  display:none;                        /* desktop: the inline nav is enough */
  align-items:center;gap:10px;cursor:pointer;
  background:none;border:1px solid var(--rule-invert);color:var(--on-dark);
  padding:11px 15px;
  font-family:var(--sans);font-size:12px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;
}
.navtoggle:hover{border-color:var(--on-dark)}
.navtoggle-bars{position:relative;display:block;width:22px;height:2px;background:currentColor;transition:background .18s ease}
.navtoggle-bars::before,.navtoggle-bars::after{
  content:"";position:absolute;left:0;width:22px;height:2px;background:currentColor;
  transition:transform .22s ease;
}
.navtoggle-bars::before{top:-7px}
.navtoggle-bars::after{top:7px}
.navtoggle[aria-expanded="true"] .navtoggle-bars{background:transparent}
.navtoggle[aria-expanded="true"] .navtoggle-bars::before{transform:translateY(7px) rotate(45deg)}
.navtoggle[aria-expanded="true"] .navtoggle-bars::after{transform:translateY(-7px) rotate(-45deg)}

.mobilenav{display:none}

@media (max-width:1000px){
  .nav{display:none}

  /* Menu button on the LEFT with the wordmark centred, which is the header
     the magazine itself uses (ISSUE N | wordmark | date). The third column is
     empty and exists only so the wordmark is optically centred rather than
     centred in the space the button leaves over. */
  .masthead-bar{display:grid;grid-template-columns:auto 1fr auto;gap:10px;align-items:center;
                padding-top:22px;padding-bottom:22px}
  .masthead-bar > a{grid-column:2;grid-row:1;justify-self:center}
  .masthead-bar > a img{width:clamp(150px,44vw,210px)}
  /* the eyebrow cannot shrink with the wordmark and stay legible - at this
     width it would have to drop to about 6px - so it goes. The footer still
     carries the Make The World Better line as text on every page. */
  .brand-eyebrow{display:none}
  .navtoggle{display:inline-flex;grid-column:1;grid-row:1;justify-self:start}
  /* the label stays for screen readers, but the icon alone carries it on a
     phone so the wordmark is not squeezed */
  .navtoggle > span:not(.navtoggle-bars){
    position:absolute;width:1px;height:1px;margin:-1px;padding:0;
    overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
  }
  /* 22px icon + this padding clears the 44x44px minimum touch target
     (WCAG 2.5.5 / Apple HIG) - the old 18px icon + 11px/12px padding landed
     at roughly 42x36, visibly small and a little short of it (Ken, mobile
     feedback, 2026-09-11) */
  .navtoggle{gap:0;padding:15px 16px}

  .mobilenav{display:block;border-top:1px solid var(--rule-invert)}
  /* must come after the display:block above, or the hidden attribute loses */
  .mobilenav[hidden]{display:none}

  /* flex-start, NOT space-between. With the trailing arrow removed in the
     de-boxing pass, space-between had nothing to push against except the
     current-page marker, so on the page you were actually on the label shot
     across to the right edge. */
  .mobilenav a{
    display:flex;align-items:center;justify-content:flex-start;gap:12px;
    min-height:56px;padding:17px var(--gut);
    font-family:var(--display);font-size:19px;font-weight:600;letter-spacing:-.01em;
    color:var(--on-dark);text-decoration:none;
    border-bottom:1px solid var(--rule-invert);
  }
  .mobilenav a:hover,.mobilenav a:focus-visible{background:var(--ink-lift)}
  .mobilenav a[aria-current]{color:#fff}
  /* every row reserves the marker slot, so the current row's dot cannot shift
     its label out of line with the others */
  .mobilenav a::before{
    content:"";flex:none;width:6px;height:6px;border-radius:50%;background:transparent;
  }
  .mobilenav a[aria-current]::before{background:var(--green)}

  .mobilenav .mn-cta{padding:18px var(--gut) 26px}
  .mobilenav .mn-cta .btn{width:100%;justify-content:center}
}

/* ======================================================================
   ARTICLE PAGE — rebuilt 2026-08-24 to the live site's own layout.

   The first migration poured the articles into this prototype's generic
   band/prose furniture. That got the words onto the page but lost the thing
   that makes a CE Magazine article look like one: the split black hero, the
   magazine folio bar, and — the part Ken caught — figures sized to the text
   column instead of blown across the viewport.

   Geometry is MEASURED off circulareconomymag.com at a 1440px viewport
   (Playwright, not eyeballed), then expressed as the ratios the live
   stylesheet actually uses:

     text column        542px   -> --ap-col
     hero image         742px   (58% of the hero container)
     hero text          43% of the hero container, 72px right padding
     fullwidth figure   542px   = 100% of the column
     centred figure     325px   = 60% of the column

   Colour tokens are the live site's own `--_ce-mag---*` values.
   ====================================================================== */

.ap{--ap-col:544px;--ap-shell:1120px;--ap-wide:736px;--ap-rail:256px;--ap-black:#1d1d1e;--ap-offwhite:#f9f9f9;--ap-blue:#3b8dcc;
    /* extra width full-width figures take to the RIGHT of the text column:
       64px column gap + 200px spacer = the slack the layout already had. */
    --ap-bleed:264px;--ap-portrait:325px}

/* ---- folio bar: Issue N | wordmark | date ---------------------------- */
.ap-folio{background:var(--ap-offwhite);border-bottom:1px solid #000}
.ap-folio-in{max-width:var(--ap-shell);margin:0 auto;padding:22px clamp(20px,4vw,60px);
             display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:16px}
.ap-folio .fm{font-family:var(--display);font-size:11.5px;font-weight:600;letter-spacing:.18em;
              text-transform:uppercase;color:var(--ink)}
.ap-folio .fm:last-child{text-align:right}
.ap-folio img{display:block;width:230px;max-width:100%;height:auto;margin:0 auto}
.ap-folio a{display:block}

/* ---- split hero: black text panel + full-bleed image ----------------- */
.ap-hero{background:var(--ap-black);color:var(--ap-offwhite);display:flex;justify-content:flex-end}
/* Ken, 2026-09-11: was `max-width:1520px;margin-left:160px`, a fixed pair
   that only matched .ap-body-in's centred `max-width:var(--ap-shell)` inset
   at one accidental viewport width (~1440px, a typical laptop). Above that
   the two drifted apart — worse the wider the screen, since this used a
   constant margin while the body centres a 1120px column. Both edges now
   come from the same formula .ap-body-in effectively uses once it hits its
   own max-width, so the hero text and the body column share one left edge
   at every desktop width instead of one lucky one. Width fills to the
   viewport's right edge itself (replacing max-width) so the image keeps its
   full bleed regardless of the inset. */
.ap-hero-in{display:flex;align-items:center;justify-content:space-between;align-self:stretch;
            margin-left:max(24px, (100% - var(--ap-shell)) / 2);
            width:calc(100% - max(24px, (100% - var(--ap-shell)) / 2))}
.ap-hero-txt{width:43%;flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;
             align-items:flex-start;gap:22px;padding:clamp(44px,6vw,80px) clamp(24px,5vw,72px) clamp(44px,6vw,80px) 0}
.ap-eyebrow{font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.28em;
            text-transform:uppercase;color:var(--ap-blue);margin:0}
.ap-hero-txt h1{font-family:var(--display);font-weight:600;letter-spacing:-.015em;line-height:1.06;
                font-size:clamp(30px,3.6vw,52px);color:var(--ap-offwhite);margin:0}
.ap-dek{font-family:var(--serif);font-size:clamp(16px,1.35vw,19px);line-height:1.5;
        color:var(--ap-offwhite);margin:0;max-width:34ch}
.ap-hero-meta{font-family:var(--sans);font-size:15px;color:var(--gray-med);margin:0}
.ap-hero-meta .sep{margin:0 .55em;opacity:.55}
.ap-hero-img{width:58%;align-self:stretch;overflow:hidden}
.ap-hero-img img{display:block;width:100%;height:100%;object-fit:cover;object-position:50% 50%}

/* ---- body: share rail | 542px column | balancing spacer -------------- */
.ap-body{display:flex;justify-content:center;align-items:flex-start;
         padding:clamp(44px,5vw,80px) 0 clamp(60px,7vw,120px)}
.ap-body-in{display:flex;justify-content:space-between;align-items:flex-start;
            width:100%;max-width:var(--ap-shell);margin:0 clamp(24px,7vw,160px);gap:clamp(24px,2.3vw,32px)}
/* rail 256 | 32 | column 544 | 32 | card 256 = 1120, the mockup's measure */
.ap-share{display:flex;justify-content:center;align-items:center;gap:30px;
          width:var(--ap-rail);min-width:150px;height:80px;flex:0 0 auto;
          border-top:1px solid var(--gray-med);border-bottom:1px solid var(--gray-med)}
.ap-share a,.ap-share button{display:grid;place-items:center;width:32px;height:32px;border:1px solid var(--gray-med);
            border-radius:50%;color:var(--gray-med-dark);background:none;padding:0;cursor:pointer;
            transition:border-color .2s,color .2s}
.ap-share button:hover{border-color:var(--ink);color:var(--ink)}
.ap-share button.is-done{border-color:var(--green);color:var(--green)}
.ap-share .ap-copied{position:absolute;left:0;right:0;top:100%;margin-top:8px;text-align:center;
            font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--green)}
.ap-share{position:relative}
.ap-share a:hover{border-color:var(--ink);color:var(--ink)}
.ap-share svg{width:15px;height:15px;display:block}
.ap-spacer{width:var(--ap-rail);min-width:0;flex:0 0 auto}

/* ---- side column: 'This article is from Issue N' card (#25 / #27 mockup) --
   The right column was a 200px spacer that balanced the share rail. Liz's
   mockup puts the issue card there: cover, one line, two actions. Sticky so it
   travels with a long read. An ad slot can share this column later; it is
   not drawn empty (#2). */
.ap-side{width:var(--ap-rail);flex:0 0 auto}
.ap-issuecard{background:var(--paper-2);padding:16px 16px 18px}
.ap-issuecard-top{display:flex;gap:16px;align-items:flex-start}
.ap-issuecard-top img{width:87px;height:auto;flex:none;box-shadow:0 4px 12px rgba(29,29,30,.14)}
.ap-issuecard-top p{font-family:var(--sans);font-size:16px;line-height:1.4;margin:0;color:var(--ink)}
.ap-issuecard-top p b{font-weight:700}
.ap-issuecard .btns{display:grid;gap:8px;margin-top:16px}
.ap-issuecard .btn{justify-content:center;padding:10px 14px;font-size:12px;letter-spacing:.1em}
@media (max-width:1279px){.ap-side{display:none}}

.ap-col{max-width:var(--ap-col);flex:1 1 var(--ap-col);min-width:0;
        font-family:var(--serif);font-size:18px;line-height:1.5;color:var(--ink)}
.ap-col > :first-child{margin-top:0}
.ap-col p{margin:0 0 1.3em}
/* body headings are bold sans in the original, NOT the serif heads the
   rest of this site uses — they read as interview questions, which is what
   they are. */
.ap-col h2{font-family:var(--sans);font-weight:700;font-size:18px;line-height:1.5;
           color:var(--ink);margin:2.2em 0 .9em}
.ap-col h2:first-child{margin-top:0}
.ap-col a{color:var(--ink);text-decoration:underline;text-decoration-thickness:1px;
          text-underline-offset:2px}
.ap-col ul,.ap-col ol{margin:0 0 1.3em;padding-left:1.3em}
.ap-col li{margin:0 0 .5em}
/* pull quote as in the mockup: centred, 24/33.6, ruled above and below, and
   the full --ap-wide measure, so it steps out of the text column */
.ap-col blockquote{margin:2.2em calc((var(--ap-wide) - var(--ap-col)) / -2);padding:26px 0;
                   border-top:1px solid var(--ink);border-bottom:1px solid var(--ink);
                   font-size:24px;line-height:1.4;color:var(--gray-dark);text-align:center;max-width:none}
.ap-col blockquote p:last-child{margin:0}

/* ---- figures ---------------------------------------------------------
   The live site caps every figure at the 542px text column. Ken asked for the
   full-width ones to run LARGER than that here (2026-08-24), so they break out
   to the right by --ap-bleed: the 64px gap plus the 200px spacer, which is dead
   space in the live layout anyway.

   Breaking out RIGHT rather than centring on the container is deliberate — it
   keeps the figure's left edge on the same vertical as the text column, so the
   column edge reads as one continuous line down the page instead of the images
   wandering out on both sides. It also keeps them clear of the share rail.

   Centred figures do NOT bleed. They are portraits, headshots and report
   covers, and enlarging those is what made them look like mugshots in the
   first place. Their width is pinned in px rather than left at 60%, so that
   widening the full-width figures cannot drag them along with it. */
.ap-fig{margin:2.2em 0;text-align:center}
.ap-fig img{display:block;width:100%;height:auto;margin:0 auto}
/* #26 / #28 (2026-09-04): full-width figures run --ap-wide (736px), centred on
   the 544px text column, per Liz's mockup. Portraits stay in-column. */
.ap-fig:not(.ap-fig--center){width:var(--ap-wide);max-width:none;margin-left:calc((var(--ap-wide) - var(--ap-col)) / -2)}
.ap-fig--center figcaption{text-align:center;margin:0 auto;max-width:46ch} /* 2026-09-04: no right bleed. The live Webflow site renders full-width figures at the 542px column (measured on twenifor, debrand, chopvalue, kore-outdoors, canada-plastics-pact); Ken asked for the same. --ap-bleed is left defined but unused. */
.ap-fig--center{width:100%}
.ap-fig--center img{width:var(--ap-portrait,325px);max-width:100%}
/* Caption: Proxima Nova 15/22.5 per Liz's 2.4 Article mockup (2026-09-04) */
.ap-fig figcaption{font-family:var(--sans);font-size:15px;line-height:1.5;
                   color:var(--gray-med-dark);padding:12px 0 0;margin:0;max-width:none;text-align:left}

.ap-contact{border-top:1px solid var(--gray-med-dark);border-bottom:1px solid var(--gray-med-dark);
            padding:22px 0;margin:2.6em 0 0;font-family:var(--sans);font-size:15.5px}
.ap-contact p{margin:0 0 8px;color:var(--gray-med-dark)}
.ap-contact p:last-child{margin:0}
.ap-contact a{color:var(--gray-med-dark);text-decoration:underline}
.ap-contact a:hover{color:var(--ink)}

.ap-next{border-top:1px solid var(--rule);margin-top:2.8em;padding-top:22px;
         font-family:var(--sans);font-size:15.5px;display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}
.ap-next > span{display:flex;flex-direction:column;gap:4px;max-width:46%}
.ap-next > span + span{text-align:right;align-items:flex-end}
/* the word does the job the glyph was doing, and says it in the reader's own
   language rather than in a symbol */
.ap-next .dir{font-family:var(--display);font-size:11px;font-weight:600;
              letter-spacing:.18em;text-transform:uppercase;color:var(--gray-med-dark)}
.ap-next a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--rule-strong)}
.ap-next a:hover{color:var(--accent);border-bottom-color:var(--accent)}
/* The arrow sits on its own line ABOVE the title on BOTH sides (Liz,
   2026-09-11). It used to be a bare text node beside the link, which put the
   left arrow above its title and the right arrow below its own. */
.ap-next .dir{display:block}

/* ---- the editor's letter --------------------------------------------------
   Liz, 2026-09-11: "i had a different layout for the letters from the editor
   since they are not categorized as articles and will always use hamish's
   headshot." So the letter does not use the article's split hero, share rail
   and issue-card columns. It is one centred column on paper: eyebrow, title,
   Hamish's headshot, his name and title, then the letter, signed. The issue
   card moves under the signature, where it is also visible on a phone - the
   article pages' right-hand card is hidden below 1280px.
   ------------------------------------------------------------------------ */
.letter{background:var(--paper)}
.letter-in{max-width:648px;margin:0 auto;padding:clamp(40px,5vw,72px) 24px clamp(56px,6vw,104px)}
.letter-head{text-align:center;border-bottom:1px solid var(--rule);padding-bottom:clamp(24px,3vw,34px)}
.letter-head h1{font-family:var(--display);font-weight:600;letter-spacing:-.015em;line-height:1.1;
                font-size:clamp(32px,4.4vw,48px);margin:12px 0 0}
/* if an eyebrow is ever put back on a letter: the article one is blue because
   it sits on the black hero panel, and on paper it needs the muted ink */
.letter-head .ap-eyebrow{margin:0;color:var(--gray-med-dark)}
.letter-portrait{display:block;width:112px;height:112px;border-radius:50%;object-fit:cover;
                 margin:clamp(22px,3vw,30px) auto 0;background:var(--gray-light)}
.letter-by{font-family:var(--display);font-size:16px;font-weight:600;letter-spacing:-.01em;margin:16px 0 0}
.letter-by span{display:block;font-family:var(--sans);font-size:14px;font-weight:400;letter-spacing:0;
                color:var(--gray-med-dark);margin-top:4px}
.letter-head .ap-hero-meta{margin-top:10px;color:var(--gray-med-dark)}
/* the share rail loses its rules and its fixed rail width here, and centres */
.letter .ap-share{width:auto;min-width:0;height:auto;border:0;margin:22px 0 0;gap:22px}
.letter .ap-col{max-width:none;flex:none;margin-top:clamp(30px,3.6vw,44px)}
/* the letter column has no wide measure beside it, so the pull quote and any
   figure stay inside it rather than stepping out by (--ap-wide - --ap-col)/2 */
.letter .ap-col blockquote{margin-left:0;margin-right:0}
.letter .ap-fig{width:auto;max-width:100%;margin-left:0}
.letter-sign{font-family:var(--display);font-size:17px;font-weight:600;letter-spacing:-.01em;
             margin:2em 0 0;line-height:1.4}
.letter-sign span{display:block;font-family:var(--sans);font-size:14.5px;font-weight:400;letter-spacing:0;
                  color:var(--gray-med-dark);margin-top:4px}
.letter-card{max-width:420px;margin:clamp(40px,5vw,64px) auto 0}
.letter .ap-next{margin-top:clamp(40px,5vw,64px)}
@media (max-width:560px){.letter-portrait{width:92px;height:92px}}

@media (max-width:1279px){
  /* width has to be restated alongside margin-left now that the base rule
     computes it from the same formula — leaving the old base `width` in
     place here would fill to the wrong right edge once margin-left changes. */
  .ap-hero-in{margin-left:40px;width:calc(100% - 40px)}
  .ap-hero-img{width:55%}
}
/* Between 1280 and 1180 the column itself is squeezed by the flex row before
   its 542px cap bites, so the bleed comes down with it. */
@media (max-width:1279px){ .ap{--ap-bleed:210px} }
@media (max-width:1180px){
  .ap{--ap-col:500px;--ap-bleed:150px;--ap-wide:620px}
  /* The spacer is gone below here, and `space-between` on two remaining items
     dumps ALL the free space between them — which shoves the text column flush
     against the container's right edge and leaves the figure bleed nowhere to
     go but off-screen. Pack left instead, so the slack the spacer used to hold
     is real space on the right that a figure can actually use. */
  .ap-body-in{justify-content:flex-start}
  .ap-share{flex-direction:column;width:auto;min-width:52px;height:auto;gap:16px;padding:14px 0}
  .ap-spacer{display:none}
}
@media (max-width:900px){
  .ap-hero-in{flex-direction:column;margin-left:0;width:100%}
  .ap-hero-txt{width:auto;margin:0 clamp(20px,5vw,24px);padding:38px 0}
  .ap-hero-img{width:100%}
  .ap-hero-img img{height:min(62vh,440px)}
  .ap-body-in{flex-direction:column;margin:0 clamp(20px,5vw,24px);gap:0}
  .ap-share{flex-direction:row;width:200px;height:auto;padding:12px 0;margin:0 0 26px}
  .ap-col{max-width:none;flex:1 1 auto}
  /* stacked single column: the figure already spans the full measure */
  .ap{--ap-bleed:0px}
  .ap-fig:not(.ap-fig--center){width:100%;margin-left:0}
  .ap-col blockquote{margin-left:0;margin-right:0}
  .ap-folio img{width:190px}
  .ap-folio .fm{font-size:9.5px;letter-spacing:.14em}
}
@media (max-width:560px){
  .ap{--ap-portrait:78%}
  .ap-folio-in{grid-template-columns:1fr auto 1fr;padding:16px 20px}
}

/* Labels that a screen reader needs but the screen does not, because the
   field carries a placeholder. */
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---------- rate card (/advertise) --------------------------------------
   Real tabular data, so a real <table>. Under 820px each row becomes a
   stacked card and the column headers move into td::before via data-label,
   because four columns of inch measurements do not survive a phone. */
.ratecard-wrap{margin:0}
.ratecard{width:100%;border-collapse:collapse;text-align:left}
.ratecard thead th{
  font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink);vertical-align:bottom;
  padding:0 20px 13px 0;border-bottom:1px solid var(--rule-strong);
}
.ratecard thead th small{
  display:block;margin-top:6px;max-width:24ch;
  font-family:var(--sans);font-size:13px;font-weight:400;letter-spacing:0;
  text-transform:none;line-height:1.45;color:var(--gray-med-dark);
}
.ratecard td,.ratecard tbody th{padding:24px 20px 24px 0;border-bottom:1px solid var(--rule);vertical-align:top}
.ratecard thead th:last-child,.ratecard td:last-child{padding-right:0;text-align:right}

.rc-fig{width:80px;padding-top:27px}
.rc-fig svg{display:block}
.rc-fig rect{fill:var(--gray-light);stroke:var(--ink);stroke-width:1.2}
.rc-fig .rc-open{fill:none}
.rc-fig .rc-gutter{stroke:var(--ink);stroke-width:1.2}

.rc-name{
  font-family:var(--display);font-size:clamp(16px,1.5vw,19px);font-weight:600;
  letter-spacing:-.01em;line-height:1.25;
}
.rc-name .sub{
  display:block;margin-top:8px;max-width:34ch;
  font-family:var(--serif);font-size:15.5px;font-weight:400;letter-spacing:0;
  line-height:1.5;color:rgba(29,29,30,.68);
}
.rc-dim{font-size:15.5px;white-space:nowrap;font-variant-numeric:tabular-nums}
.rc-rate{
  font-family:var(--display);font-size:clamp(19px,1.8vw,23px);font-weight:600;
  letter-spacing:-.015em;white-space:nowrap;
}
.rc-note{font-size:15.5px;line-height:1.6;color:var(--gray-med-dark);margin:22px 0 0;max-width:74ch}
.rc-note strong{color:var(--ink);font-weight:600}

@media (max-width:820px){
  .ratecard thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}
  .ratecard,.ratecard tbody,.ratecard tr,.ratecard td,.ratecard tbody th{display:block;width:auto}
  .ratecard tr{border-bottom:1px solid var(--rule);padding:22px 0}
  .ratecard tr:first-child{border-top:1px solid var(--rule-strong)}
  .ratecard td,.ratecard tbody th{border:0;padding:0}
  .ratecard td:last-child{text-align:left}
  .rc-fig{padding:0 0 14px}
  .rc-name .sub{max-width:52ch}
  .rc-dim,.rc-rate{margin-top:12px}
  .ratecard td[data-label]::before,.ratecard tbody th[data-label]::before{
    content:attr(data-label) " ";
    font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.14em;
    text-transform:uppercase;color:var(--ink);display:block;margin-bottom:3px;
  }
  .rc-rate{font-size:21px}
}

/* ---------- forms ------------------------------------------------------
   The contact form on /contact, and the state the mailing-list band shows
   after a submission. Built to the same rules as the rest of the site:
   square corners, a single 1px rule, Termina only for the small uppercase
   labels, and the green reserved for focus and the submit button. The
   ---------------------------------------------------------------------- */

.formwrap{
  background:#fff;border:1px solid var(--rule-strong);
  padding:clamp(24px,3.2vw,40px);
}
/* both forms set their own display, which outranks the hidden attribute:
   forms.js hides the form once it has been sent, so say so explicitly */
.formwrap[hidden],.signup[hidden],.field[hidden]{display:none}
.formgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px 22px}
.field{display:flex;flex-direction:column;gap:7px;min-width:0}
.field--wide{grid-column:1 / -1}
.field label{
  font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink);
}
.field label .opt{
  font-family:var(--sans);font-size:11.5px;font-weight:400;letter-spacing:.02em;
  text-transform:none;color:var(--gray-med-dark);margin-left:6px;
}
.field input,.field select,.field textarea{
  font-family:var(--sans);font-size:16px;line-height:1.5;color:var(--ink);
  background:#fff;border:1px solid var(--rule-strong);border-radius:0;
  padding:13px 14px;width:100%;
}
.field textarea{resize:vertical;min-height:152px}
.field select{
  appearance:none;-webkit-appearance:none;padding-right:42px;cursor:pointer;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%231d1d1e' stroke-width='1.5'%3E%3Cpath d='M1 1.5 6 6.5l5-5'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 15px center;background-size:12px 8px;
}
.field input::placeholder,.field textarea::placeholder{color:var(--gray-med-dark)}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:2px solid var(--green);outline-offset:-2px;border-color:var(--green);
}
.field input:user-invalid,.field textarea:user-invalid{border-color:#b3261e}

/* the consent checkbox */
.field--check{grid-column:1 / -1;flex-direction:row;align-items:flex-start;gap:12px}
.field--check input{width:18px;height:18px;flex:none;margin-top:3px;accent-color:var(--green)}
.field--check label{
  font-family:var(--sans);font-size:15.5px;font-weight:400;letter-spacing:0;
  text-transform:none;line-height:1.55;color:rgba(29,29,30,.78);
}

/* Cloudflare Turnstile. The widget is a cross-origin iframe, so its interior
   cannot be styled from here - only the space around it. forms.js renders it
   with appearance:interaction-only, so the container is empty for almost
   everyone, and :not(:empty) keeps an unexplained gap from opening above the
   button in that case. */
.cf-turnstile{max-width:100%;grid-column:1 / -1}
.cf-turnstile:not(:empty){margin-bottom:18px}
.ts-note{
  grid-column:1 / -1;margin:14px 0 0;font-size:13px;line-height:1.5;
  color:var(--gray-med-dark);
}
.ts-note a{color:var(--gray-med-dark);text-decoration:underline}
.ts-note a:hover{color:var(--ink)}
.signup .ts-note,.signup .cf-turnstile{grid-column:1 / -1}
.newsband .ts-note{margin-top:10px}

.formfoot{
  grid-column:1 / -1;display:flex;flex-wrap:wrap;align-items:center;gap:18px 24px;
  border-top:1px solid var(--rule);padding-top:24px;margin-top:2px;
}
.formfoot .fineprint{margin:0;max-width:46ch}

.formstatus{margin:0;font-size:15.5px;line-height:1.5}
.formstatus:empty{display:none}
.formstatus--bad{color:#b3261e}
.formstatus--ok{color:#1f7a3f}

.formdone{
  background:#fff;border:1px solid var(--green);border-left-width:4px;
  padding:clamp(24px,3.2vw,38px);
}
.formdone h2{margin:0 0 10px}
.formdone p{margin:0;max-width:56ch}
.formdone:focus{outline:none}

/* the mailing-list band's own confirmation, on the ink ground */
.newsband .formdone{background:none;border-color:var(--green);padding:18px 20px}
.newsband .formdone p{font-size:15.5px;color:inherit}

@media (max-width:720px){
  .formgrid{grid-template-columns:1fr}
}

/* ---------- /contact --------------------------------------------------- */

.contact-grid{
  display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);
  gap:clamp(30px,4.5vw,64px);align-items:start;
}
.contact-side h3{font-size:17px;margin:0 0 8px}
.contact-side .route{border-top:1px solid var(--rule-strong);padding:20px 0 0;margin:0 0 26px}
.contact-side .route p{margin:0;font-size:15.5px;line-height:1.6;color:var(--gray-med-dark)}
.contact-side .route a{color:var(--ink);text-decoration:none;border-bottom:1px solid var(--rule-strong)}
.contact-side .route a:hover{border-bottom-color:var(--green);color:var(--green)}

@media (max-width:900px){
  .contact-grid{grid-template-columns:1fr}
}

/* ---------- /order: the 10+2 package ------------------------------------
   The copy, the imagery and the section order are Liz's Webflow "Purchase"
   page (pageId 6917d189b3f9f287fe78f80e), pulled verbatim through the Webflow
   Data API - see tools/webflow_pull.py and the README. Nothing here was
   written or invented for the web build; only the type, colour and spacing
   come from this site's own system so the page sits inside the magazine
   rather than beside it.
   ---------------------------------------------------------------------- */
/* Ken, 2026-09-11: was var(--ink), identical to .masthead's background, so
   the hero had no visible seam under the nav. Now the same --paper-2 the
   homepage hero uses for the same reason, so the hero flips to dark-on-light
   below and the four rules right after it (quote, read-reviews, role, trust
   rule) go with it — they were the dark-ground versions of those colours and
   are only ever used inside this hero. */
.ord-hero{background:var(--paper-2);color:var(--ink);padding:clamp(44px,5.5vw,84px) 0 0}
.ord-hero-grid{display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,.95fr);
               gap:clamp(32px,5vw,72px);align-items:center}
.ord-h1{font-family:var(--display);font-weight:600;letter-spacing:-.02em;line-height:1.06;
        font-size:clamp(34px,4.4vw,58px);margin:0;max-width:16ch}
.ord-green{color:var(--accent)}
.ord-lede{list-style:none;margin:clamp(22px,2.6vw,32px) 0 0;padding:0;display:grid;gap:10px}
.ord-lede li{font-family:var(--display);font-size:clamp(17px,1.5vw,20px);font-weight:500;
             letter-spacing:-.01em;line-height:1.35}
.ord-reviews{display:flex;align-items:center;gap:16px;margin-top:clamp(24px,3vw,34px)}
.ord-stars{display:inline-flex;gap:4px}
.ord-stars svg{width:16px;height:16px;fill:var(--accent);display:block}
.ord-quote{margin:clamp(20px,2.4vw,28px) 0 0;padding:0 0 0 20px;border-left:2px solid var(--accent)}
.ord-quote blockquote{font-family:var(--sans);font-size:16px;line-height:1.55;margin:0;
                      color:var(--ink);max-width:56ch}
.ord-quote figcaption{margin-top:14px;display:grid;gap:2px}
.ord-who{font-family:var(--display);font-size:15px;font-weight:600;letter-spacing:-.01em}
.ord-role{font-family:var(--sans);font-size:14px;color:var(--gray-med-dark)}
.ord-btns{display:flex;flex-wrap:wrap;gap:12px;margin-top:clamp(26px,3vw,36px)}
.ord-hero-img img{display:block;width:100%;height:auto}

/* Ken, 2026-09-11: the check sits on the middle of its label, not the top of
   it, so the two-line item does not look mis-set beside the one-line ones, and
   the bar has room under it rather than ending flush on the band edge. */
.ord-trust{list-style:none;margin:clamp(40px,5vw,72px) 0 0;
           padding:clamp(28px,3.4vw,40px) 0 clamp(40px,4.6vw,60px);
           border-top:1px solid var(--rule);display:grid;
           /* auto-fit, not a fixed three: the bar lost an item on 2026-09-11
              and should not leave a gap where it was, or need touching again
              if one is added. */
           grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:24px clamp(24px,3vw,48px)}
.ord-trust li{display:flex;align-items:center;gap:14px}
.ord-trust svg{width:22px;height:22px;flex:none;fill:var(--accent);color:var(--accent)}
.ord-trust p{font-family:var(--display);font-size:14.5px;font-weight:600;letter-spacing:-.005em;
             line-height:1.35;margin:0}

/* the shared measure for this page's running text */
.ord-p{font-family:var(--serif);font-size:17px;line-height:1.6;color:rgba(29,29,30,.82);
       margin:0 0 1.1em;max-width:68ch}
.ord-p--strong{font-family:var(--display);font-size:17.5px;font-weight:600;letter-spacing:-.01em;
               color:var(--ink)}
.ord-h2{margin:0 0 clamp(26px,3vw,40px)}

.ord-gap{display:grid;grid-template-columns:minmax(0,.8fr) minmax(0,1.2fr);
         gap:clamp(28px,5vw,72px);align-items:start}
.ord-gap h2{margin:0;max-width:14ch}

.ord-three{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(26px,3.4vw,48px)}
.ord-three img{display:block;width:72px;height:72px;margin:0 0 18px}
.ord-three h3{margin:0 0 10px}
.ord-three p{font-family:var(--serif);font-size:16px;line-height:1.55;color:rgba(29,29,30,.75);margin:0}

.ord-num{display:grid;grid-template-columns:auto minmax(0,1fr);gap:clamp(20px,3vw,44px);
         padding:clamp(28px,3.4vw,44px) 0;border-top:1px solid var(--rule)}
.ord-num:first-child{border-top:0;padding-top:0}
.ord-num-n{font-family:var(--display);font-size:clamp(40px,5vw,64px);font-weight:600;
           letter-spacing:-.03em;line-height:1;color:var(--accent)}
.ord-num-eyebrow{font-family:var(--display);font-size:11px;font-weight:600;letter-spacing:.18em;
                 text-transform:uppercase;color:var(--gray-med-dark);margin:0 0 10px}
.ord-num h3{margin:0 0 14px}
.ord-checks{list-style:none;margin:0;padding:0;display:grid;gap:9px}
.ord-checks li{font-family:var(--display);font-size:15px;font-weight:500;letter-spacing:-.005em;
               padding-left:26px;position:relative}
.ord-checks li::before{content:"";position:absolute;left:0;top:.35em;width:14px;height:14px;
  background:var(--accent);
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6.2 11.3 3.1 8.2l1.1-1.1 2 2 4.6-4.6 1.1 1.1z'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M6.2 11.3 3.1 8.2l1.1-1.1 2 2 4.6-4.6 1.1 1.1z'/%3E%3C/svg%3E") center/contain no-repeat}

.ord-faq{display:grid;gap:clamp(24px,3vw,36px);max-width:78ch}
.ord-q{font-family:var(--display);font-size:17.5px;font-weight:600;letter-spacing:-.01em;margin:0 0 10px}

.ord-strip{display:grid;grid-template-columns:repeat(4,minmax(0,1fr))}
.ord-strip img{display:block;width:100%;height:100%;aspect-ratio:4/3;object-fit:cover}

/* Ken, 2026-09-11: was var(--ink) — same light-grey treatment as .ord-hero
   above, and for the same reason. Everything under it that assumed a dark
   ground (the muted-on-dark greys, the invert-opacity rules) flips with it;
   nothing here is reused outside this section. */
.ord-close{background:var(--paper-2);color:var(--ink);padding:clamp(52px,6.5vw,96px) 0;text-align:center}
.ord-close .ord-num-eyebrow{color:var(--gray-med-dark)}
.ord-close .ord-h2{max-width:22ch;margin-left:auto;margin-right:auto}
.ord-close .ord-p{color:var(--gray-med-dark);max-width:64ch;margin-left:auto;margin-right:auto}
.ord-close .ord-btns{justify-content:center}
.ord-launch{font-family:var(--sans);font-size:14.5px;color:var(--gray-med-dark);margin:clamp(28px,3.4vw,44px) 0 0}
.ord-fine{font-family:var(--sans);font-size:13px;line-height:1.5;color:var(--gray-med-dark);
          margin:12px auto 0;max-width:70ch}


@media (max-width:1000px){
  .ord-hero-grid{grid-template-columns:1fr}
  .ord-hero-img{max-width:420px}
  .ord-gap{grid-template-columns:1fr}
  .ord-three{grid-template-columns:1fr;gap:30px}
  .ord-strip{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:760px){
  .ord-trust{grid-template-columns:1fr;gap:14px}
  .ord-num{grid-template-columns:1fr;gap:10px}
}

/* ---- /order: the issue picker ------------------------------------------
   A Stripe Payment Link opens with its line items fixed and every quantity at
   one, so it cannot be a picker. This is ours: three rows, a stepper each, a
   live subtotal, and one button that posts the selection to /api/checkout.
   ---------------------------------------------------------------------- */
.ord-pick{max-width:640px;margin:clamp(32px,4vw,48px) auto 0;text-align:left}
.ord-pick-row{display:grid;grid-template-columns:44px minmax(0,1fr) auto;gap:16px;align-items:center;
              padding:16px 0;border-top:1px solid var(--rule)}
.ord-pick-row:first-child{border-top:0}
.ord-pick-row img{width:44px;height:auto;box-shadow:0 2px 8px rgba(0,0,0,.18);opacity:.75;
                  transition:opacity .2s}
.ord-pick-row.is-picked img{opacity:1}
.ord-pick-name{display:grid;gap:3px;min-width:0}
.ord-pick-issue{font-family:var(--display);font-size:15.5px;font-weight:600;letter-spacing:-.005em;
                line-height:1.3}
.ord-pick-sub{font-family:var(--sans);font-size:13.5px;color:var(--gray-med-dark)}
.ord-qty{display:flex;align-items:center;gap:2px;border:1px solid var(--rule-strong)}
.ord-qty button{width:34px;height:34px;background:none;border:0;cursor:pointer;color:var(--ink);
                font-family:var(--sans);font-size:17px;line-height:1;padding:0}
.ord-qty button:hover{background:rgba(29,29,30,.06)}
.ord-qty input{width:38px;height:34px;background:none;border:0;color:var(--ink);text-align:center;
               font-family:var(--display);font-size:15px;font-weight:600;padding:0;
               -moz-appearance:textfield;appearance:textfield}
.ord-qty input::-webkit-outer-spin-button,
.ord-qty input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.ord-qty input:focus-visible{outline:2px solid var(--accent);outline-offset:1px}

.ord-total{display:flex;justify-content:space-between;align-items:baseline;
           margin-top:6px;padding-top:18px;border-top:1px solid var(--rule-strong);
           font-family:var(--display);font-weight:600;letter-spacing:-.01em}
.ord-total span:first-child{font-size:12px;letter-spacing:.16em;text-transform:uppercase;
                            color:var(--gray-med-dark)}
.ord-total span:last-child{font-size:clamp(22px,2.4vw,28px)}
.ord-pick-go{width:100%;justify-content:center;margin-top:20px}
.ord-pick-go[disabled]{opacity:.4;cursor:not-allowed}
.ord-pick-note{font-family:var(--sans);font-size:13px;color:var(--gray-med-dark);
               margin:12px 0 0;text-align:center}
.ord-pick .formstatus{margin-top:10px;text-align:center}
@media (max-width:560px){
  .ord-pick-row{grid-template-columns:36px minmax(0,1fr);gap:12px}
  .ord-pick-row img{width:36px}
  .ord-qty{grid-column:2;justify-self:start}
}
