/* The palette and the type scale. Lives in its own file because
   index.html is no longer the only page that paints in it: method.html
   carries the long-form reasoning and has to be the same dark, with the
   same ramp. Two copies of numbers this carefully measured would drift
   the first time one of them was adjusted.

   Everything here is a custom property. No element is styled from this
   file — each page keeps its own layout rules. */

/* ---------- THE PALETTE, IN TWO SCHEMES ----------
 *
 * It follows the phone. :root carries LIGHT and the media query
 * carries DARK, which is the way round that degrades safely: a
 * browser that does not understand the query gets the scheme whose
 * tokens are plain defaults rather than overrides.
 *
 * THE BRAND COLOURS ARE EXACT, and they come off the mark:
 *
 *   navy  #141A2E   green #1E9E6A   lime  #8FBE3A
 *   amber #F0A32B   red   #E2452B
 *
 * They are used AS GIVEN wherever they are a fill -- the carbon bar,
 * the gold badge, an accent button. They are not all legible as TEXT
 * on every ground, and on paper most of them are not legible at all:
 * lime on white is 2.19:1 and amber 2.10:1, less than half of what
 * AA asks. So each one has a text twin, the same hue moved until it
 * passes, and the rule is simply which of the two a thing is:
 *
 *   --ramp-2      a swatch, a bar segment, a fill
 *   --ramp-2-ink  the same idea said in words
 *
 * Nothing here is judged by eye. contrast-check.mjs measures every
 * pair in both schemes and fails on a colour it has not been shown.
 */
:root{
  color-scheme: light dark;

  /* On paper the raised step goes DOWN, not up: there is nothing
     above white. A tint of the ground reads as the same move. */
  --accent:#8FBE3A;
  --on-accent:#141A2E;
  /* ---------- A PICKED ROW HAS TO BE VISIBLE ----------
     #F3FBDD as specified is ΔL* 2.66 against a white card, which is
     under the ~3 where a surface stops reading as the same surface
     -- the tint was there and you could not see it. Same hue, two
     steps deeper, ΔL* 4.69, and --ink on it is still 15.34:1. This
     is the one place the brief's token is not used verbatim, and it
     is in service of what the brief asked the token to DO. */
  --gold:#F2C14E;

  /* THE ACCENT IS A FILL, NOT A VOICE. Lime on white is 2.19:1 --
     less than half of AA -- so anything that says a word in the
     accent says it in this instead. On the dark ground the accent
     is already 7:1 and the two are the same colour. */

  /* THE MARK ON THE CARBON BAR. The same value as --ink, and a token
     of its own anyway: it is a FILL, it sits on the four ramp
     segments rather than on a card, and the check that stops a text
     colour being used as a surface would otherwise have to make an
     exception for it. A role, not an alias.

     AND IT IS NAVY IN BOTH SCHEMES. It does not sit on the page, it
     sits on lime and amber, and a light marker cannot be seen on
     those at all -- 1.83:1 and 1.76:1, measured. Navy is 4.21:1 at
     its worst, on the red band. A dark mark on a bright bar is the
     same mark whatever the phone is set to. */
  --marker:#141A2E;

  /* THE 2px NAVY EDGE the brief asks for on paper. On a light ground
     a lime fill has no edge of its own -- it floats -- so the accent
     button, the ticks and the active tab are drawn round. In the dark
     scheme this is 0 and the fill carries itself. */

  /* The carbon ramp as FILLS, exactly the brand five. */
  --ramp-1:#1E9E6A;   /* plant        */
  --ramp-2:#8FBE3A;   /* low animal   */
  --ramp-3:#F0A32B;   /* dairy, pork  */
  --ramp-4:#E2452B;   /* beef         */
  /* and as TEXT, on paper: measured 5.34 / 5.25 / 5.98 / 6.07 */

  /* ---------- names the pages already paint in ----------
     Ten pages were written against these and they still mean what
     they meant; pointing them at the new tokens is what keeps this a
     restyle rather than a rewrite of every file. */
  --paper:var(--card);
  --sunken:var(--card-raised);
  --rule:var(--border);
  --dim:var(--muted);
  --ink-soft:var(--muted);
  --t1:var(--ramp-1-ink);
  --t2:var(--ramp-2-ink);
  --t3:var(--ramp-3-ink);
  --t4:var(--ramp-4-ink);
  /* Used by three pages and never defined anywhere -- so they
     resolved to nothing and the properties were dropped. A heading
     tint, a warning tint and a type step, all silently absent. */
  --mark:var(--accent);
  --sect:var(--muted);
  --warn:var(--ramp-3-ink);

  /* ---------- the shape of a card ----------
     One radius and one border, so a card is the same object on every
     page. The step between the ground and a card is what stops the
     screen reading as one sheet. */
  --radius:16px;
  --radius-sm:10px;
  --card-border:1px solid var(--border);

  /* ---------- type ----------
   * Every size comes from here, in rem, so 1rem is whatever the
   * READER has told their browser they need.
   *
   *   xs    12px   ruler ticks, column heads, uppercase labels
   *   sm    14px   units, secondary figures, chips
   *   base  16px   body, prose, table rows
   *   md    18px   emphasis, touch glyphs
   *   lg    22px   the product name
   *   xl    28px   a countdown figure
   *
   * Anything a finger taps into stays at base or above: iOS Safari
   * zooms the whole page when a focused input is under 16px, which
   * yanked the layout sideways mid-typing. */
  --t-xs:   0.75rem;
  --t-sm:   0.875rem;
  --t-base: 1rem;
  --t-md:   1.125rem;
  --t-lg:   1.375rem;
  --t-xl:   1.75rem;

  /* Archivo for words, Plex Mono for anything you would compare two
     of: counts, countdowns, percentages, wallet addresses. */
  --font:"Archivo",system-ui,-apple-system,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,monospace;
}

/* ---------- THE NINETEEN TOKENS THAT DIFFER BY SCHEME ----------
 *
 * Each value is written ONCE, here, as --l-* and --d-*. The three
 * rules below only ASSIGN them; none of them contains a colour. That
 * is the whole point: there are now three ways to arrive at dark --
 * the phone says so, the reader chose it, the reader chose light
 * while the phone says dark -- and a palette copied into three
 * places is a palette that is about to disagree with itself.
 *
 * Everything that is the same in both schemes stays in :root above
 * and is not repeated at all.
 */
:root{
  /* light */
  --l-bg:#F6F5F0;         --l-card:#FFFFFF;
  --l-card-raised:#F1F0EA; --l-border:#DEDBD2;
  --l-ink:#141A2E;        --l-muted:#55625E;
  --l-ink-soft:#55625E;
  --l-selected-row:#EBF7C8;
  --l-link:#157A51;       --l-accent-ink:#55761E;
  --l-accent-edge:2px solid #141A2E;
  --l-ramp-1-ink:#157A51; --l-ramp-2-ink:#55761E;
  --l-ramp-3-ink:#8A5905; --l-ramp-4-ink:#B82F18;
  --l-gold-ink:#7A590E;

  /* dark */
  --d-bg:#0B1513;         --d-card:#172824;
  --d-card-raised:#20352F; --d-border:#2E433E;
  --d-ink:#EDEBE4;        --d-muted:#A9B8B3;
  --d-ink-soft:#C7D1CD;
  --d-selected-row:#2A3A1C;
  --d-link:#8FBE3A;       --d-accent-ink:#8FBE3A;
  --d-accent-edge:1px solid #8FBE3A;
  --d-ramp-1-ink:#1E9E6A; --d-ramp-2-ink:#8FBE3A;
  --d-ramp-3-ink:#F0A32B; --d-ramp-4-ink:#F8836F;
  --d-gold-ink:#F2C14E;
}

/* AUTO IS THE DEFAULT, and light is what :root resolves to. */
:root, :root[data-theme="light"]{
  --bg:var(--l-bg);                 --card:var(--l-card);
  --card-raised:var(--l-card-raised); --border:var(--l-border);
  --ink:var(--l-ink);               --muted:var(--l-muted);
  --ink-soft:var(--l-ink-soft);     --selected-row:var(--l-selected-row);
  --link:var(--l-link);             --accent-ink:var(--l-accent-ink);
  --accent-edge:var(--l-accent-edge);
  --ramp-1-ink:var(--l-ramp-1-ink); --ramp-2-ink:var(--l-ramp-2-ink);
  --ramp-3-ink:var(--l-ramp-3-ink); --ramp-4-ink:var(--l-ramp-4-ink);
  --gold-ink:var(--l-gold-ink);
}

/* THE PHONE SAYS DARK -- unless the reader has said light. The
   :not() is what makes the choice beat the setting, and it has to be
   here rather than only on the attribute rule below: without it a
   reader who picks Light on a dark phone gets this block anyway. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:var(--d-bg);                 --card:var(--d-card);
    --card-raised:var(--d-card-raised); --border:var(--d-border);
    --ink:var(--d-ink);               --muted:var(--d-muted);
    --ink-soft:var(--d-ink-soft);     --selected-row:var(--d-selected-row);
    --link:var(--d-link);             --accent-ink:var(--d-accent-ink);
    --accent-edge:var(--d-accent-edge);
    --ramp-1-ink:var(--d-ramp-1-ink); --ramp-2-ink:var(--d-ramp-2-ink);
    --ramp-3-ink:var(--d-ramp-3-ink); --ramp-4-ink:var(--d-ramp-4-ink);
    --gold-ink:var(--d-gold-ink);
  }
}

/* THE READER SAID DARK, whatever the phone says. */
:root[data-theme="dark"]{
  --bg:var(--d-bg);                 --card:var(--d-card);
  --card-raised:var(--d-card-raised); --border:var(--d-border);
  --ink:var(--d-ink);               --muted:var(--d-muted);
  --ink-soft:var(--d-ink-soft);     --selected-row:var(--d-selected-row);
  --link:var(--d-link);             --accent-ink:var(--d-accent-ink);
  --accent-edge:var(--d-accent-edge);
  --ramp-1-ink:var(--d-ramp-1-ink); --ramp-2-ink:var(--d-ramp-2-ink);
  --ramp-3-ink:var(--d-ramp-3-ink); --ramp-4-ink:var(--d-ramp-4-ink);
  --gold-ink:var(--d-gold-ink);
}

/* AND THE NATIVE CHROME FOLLOWS THE CHOICE TOO -- scrollbars, the
   select dropdown, and above all autofill, which otherwise paints a
   white block over an input and hides what was typed. */
:root[data-theme="light"]{ color-scheme: light; }
:root[data-theme="dark"]{ color-scheme: dark; }


/* ---------- the boost banner ---------- */

/* THE FIRST THING ON THE PAGE AND THE LARGEST TYPE ON IT, because the
   multiplier decides what a shop is worth before anybody goes shopping
   and it used to be discoverable only at the moment of claiming.

   HIGH CONTRAST, MEASURED. The number paints in --ink on --sunken, which
   is 16.4:1 — above the 13.79:1 body text manages on --paper, because
   this is the one line on the page that has to be readable at arm's
   length in a shop. The halation the palette note warns about applies to
   long prose; this is four words at 2rem, where the weight of the glyphs
   carries it. */
.boost{
  background:var(--sunken);
  border-bottom:1px solid var(--rule);
  padding:18px 16px 14px;
}
.boost.hidden{ display:none; }

/* THE WHOLE ARITHMETIC ON ONE LINE, so it is set to fit one rather than
   to be the largest thing on the page. It used to hold four characters
   ("2.25x") at up to 2.5rem; it now holds "2.25x NFT x 1.5x vote = 3.38x"
   and at that size it was three rows on a 390px phone. The ANSWER keeps
   the weight -- the <b> below -- and the workings are set quieter beside
   it, which is the hierarchy the old single figure had by being alone. */
.boostNum{
  font-family:"Archivo",system-ui,sans-serif;
  font-weight:500;
  /* Sized so that a 390px phone — the narrowest this is designed for
     — fits the badge and the whole arithmetic on ONE row for every
     combination the server can send. Measured, not guessed: at
     4.4vw the longest of them took two. */
  font-size:clamp(0.9375rem, 3.9vw, 1.125rem);
  line-height:1.3;
  letter-spacing:-0.01em;
  color:var(--ink-soft);
}
.boostNum b{ font-weight:900; color:var(--ink); letter-spacing:-0.02em; }
/* Said, not implied. combine() clamps the product at BOOST_CAP, so the
   two figures beside this can multiply to more than the total. */
.boostCap{ color:var(--dim); font-size:var(--t-sm, 0.875rem); }
/* The waiting state is deliberately quieter than a number. It is not an
   error and it is not an answer, and it should not look like either. */
.boostNum.checking{ color:var(--dim); font-weight:700; }

/* ---- the ladders, behind the toggle ---- */
/* A REAL <details>: it opens with no JavaScript, takes the keyboard and
   announces its own state. The default triangle is replaced because it
   is a different shape in every browser and this one has to sit on a
   baseline with the rest of the type. */
.boostMore{ margin-top:10px; }
.boostMore.hidden{ display:none; }
.boostMore > summary{
  list-style:none; cursor:pointer; display:inline-flex; align-items:baseline; gap:6px;
  font-family:"Archivo",system-ui,sans-serif;
  font-size:var(--t-sm, 0.875rem); font-weight:700;
  letter-spacing:.06em; text-transform:uppercase; color:var(--ink-soft);
  padding:6px 0;
}
.boostMore > summary::-webkit-details-marker{ display:none; }
.boostMore > summary::after{ content:"\25be"; font-size:.9em; }
.boostMore[open] > summary::after{ content:"\25b4"; }
.boostMore > summary:focus-visible{ outline:3px solid var(--t1); outline-offset:2px; }
/* The progress line and the badge share came in here with the ladders. */
.boostMore .tierProg{ margin:2px 0 0; font-size:var(--t-sm, 0.875rem); color:var(--ink-soft); }
.boostMore .tierProg:empty{ display:none; }

.boostTiers{ margin-top:14px; display:grid; gap:12px; }
.boostGroup h3{
  margin:0 0 4px;
  font-family:"Archivo",system-ui,sans-serif;
  font-size:var(--t-sm, 0.875rem);
  font-weight:700;
  color:var(--ink-soft);
  text-transform:none;
}
.boostSub{ font-weight:400; color:var(--dim); }
.boostGroup ul{ margin:0; padding:0; list-style:none; }
.boostGroup li{
  display:flex; justify-content:space-between; gap:12px;
  padding:3px 0;
  font-size:var(--t-base);
  color:var(--ink-soft);
}
.boostGroup li b{ font-family:"IBM Plex Mono",monospace; font-weight:500;
                  color:var(--ink); }
.boostSum{
  margin:2px 0 0;
  font-size:var(--t-sm, 0.875rem);
  color:var(--dim);
}

/* ---------- notices ----------
 *
 * Moved here from index.html when the vote reminder reached the claims
 * and leaderboard pages. A bordered aside that looks like a warning on
 * one page and like body text on another is two different promises
 * about the same sentence.
 */
/* ---------- notices ----------
 *
   THE SLOT THE WEEK TILE LEAVES EMPTY. #week and #weekClaims both
   carry .empty{display:none}, so a wallet that has never claimed sees
   nothing at all above the scanner — no countdown, no total, no
   instructions. The one person on the page who does not know what to
   do is the one person the page says nothing to.

   Shaped after .held rather than .warn for the same reason .held is:
   none of this is an error. A first claim not yet made and a round
   about to close are ordinary states with something worth saying. */
#notices[hidden]{display:none}
.notice{
  font-family:"Archivo",system-ui,sans-serif;font-size:var(--t-base);line-height:1.55;
  border-left:3px solid var(--t3);padding:8px 0 8px 12px;margin:12px 0;
  color:var(--ink-soft);
}
.notice b{color:var(--ink)}
.notice[hidden]{display:none}
/* The steps are a list and read as one. Numbers rather than bullets
   because the order is the content: photographing the receipt before
   scanning is the one mistake this panel exists to prevent. */
.notice ol{margin:8px 0 0;padding-left:20px}
.notice ol li{margin:4px 0}
/* Quieter than the steps above it and separated from them, because it
   is a different kind of sentence: the steps are what to do now, and
   this is about a later week. */
.notice .vote{display:block;margin-top:10px;font-size:var(--t-sm);color:var(--dim)}


/* ==========================================================
   THE SHAPE OF THE SITE
   ==========================================================
 *
 * This file used to say "No element is styled from this file --
 * each page keeps its own layout rules." That is what produced ten
 * pages of slightly different cards: a square 2px outline here, a
 * rounded one there, three different button heights, and the page
 * ground painted the same colour as the things standing on it.
 *
 * So the SHAPE lives here now, with the palette, and a page keeps
 * only what is genuinely its own. Rules below are deliberately low
 * specificity -- a single class or element -- so a page that needs
 * to differ still can, by being more specific rather than by
 * redefining the look.
 */

html{ background:var(--bg); }
body{
  background:var(--bg);
  color:var(--ink);
  font-family:var(--font);
}

/* ---------- a card ----------
 * One radius, one hairline, one ground, and a clear step up from the
 * page. .panel, .sect, .tile and .card are the four names ten pages
 * already use for the same object. */
.card, .panel, .sect, .tile, .round, .notice.boxed{
  background:var(--card);
  border:var(--card-border);
  border-radius:var(--radius);
}

/* ---------- numbers are mono ----------
 * Anything a reader would compare two of: counts, countdowns,
 * percentages, wallet addresses, totals. */
.num, .count, .pct, .tot, .addr, .wallet, .clock b, .tile .n,
.boostGroup li b{
  font-family:var(--mono);
  font-variant-numeric:tabular-nums;
}

/* ---------- buttons ----------
 * Bold, uppercase, and never shorter than a finger. 44px is the
 * floor in both Apple's and Google's guidance and several of these
 * were 38. */
button, .btn, a.btn{
  font-family:var(--font);
  font-weight:700;
  letter-spacing:.08em;
  text-transform:uppercase;
  min-height:44px;
  border-radius:var(--radius-sm);
  cursor:pointer;
}

/* THE MAIN ACTION: accent fill, navy text, and on paper a navy edge
   -- a lime block on a white ground has no silhouette of its own. */
.btn-primary, button.go{
  background:var(--accent);
  color:var(--on-accent);
  border:var(--accent-edge);
  width:100%;
}
.btn-primary[disabled], button.go[disabled]{
  background:var(--card-raised);
  border:1px solid var(--border);
  color:var(--muted);
  cursor:not-allowed;
}

/* A SECONDARY ACTION is the same shape, hollow. */
.btn-quiet, button.off{
  background:transparent;
  color:var(--ink);
  border:1px solid var(--border);
}

/* Ticks and radios take the accent rather than the browser's blue. */
input[type="checkbox"], input[type="radio"]{ accent-color:var(--accent); }

/* One focus ring everywhere, and it is the accent. */
:focus-visible{ outline:3px solid var(--accent); outline-offset:2px; }

/* ---------- a list of links ----------
 * One card, dividers between, an accent arrow at the end. The
 * leaderboard, the sources list and the FAQ were three different
 * shapes for the same thing. */
.linkList{
  list-style:none; margin:0; padding:0;
  background:var(--card);
  border:var(--card-border);
  border-radius:var(--radius);
  overflow:hidden;
}
.linkList li + li{ border-top:1px solid var(--border); }
.linkList a{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:14px 16px; min-height:44px; box-sizing:border-box;
  color:var(--ink); text-decoration:none;
}
.linkList a::after{
  content:"\2192"; color:var(--accent-ink); font-weight:700; flex:none;
}
.linkList a:hover{ background:var(--card-raised); }

/* ---------- the camera viewer ----------
 * Named so no page carries a bare colour, but deliberately the SAME
 * in both schemes: this is the chrome around a live camera preview,
 * and a receipt is judged against black whatever the phone's setting
 * says. A light-mode camera viewer would be a white border reflecting
 * off the thing being photographed. */
:root{ --shade:#000; --on-shade:#fff; }
