/* IBM Plex, latin subset only, self hosted. SIL Open Font License 1.1.
   Plex Sans is shipped by Google as ONE variable file: requesting 400, 500 and
   600 returned three byte identical copies. It is stored once and declared
   across the weight range, which is 91KB per page load saved for nothing. */
@font-face{font-family:'IBM Plex Sans';font-style:normal;font-weight:100 700;font-display:swap;src:url('/fonts/IBMPlexSans-var.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Serif';font-style:normal;font-weight:600;font-display:swap;src:url('/fonts/IBMPlexSerif-600.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:400;font-display:swap;src:url('/fonts/IBMPlexMono-400.woff2') format('woff2')}
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:500;font-display:swap;src:url('/fonts/IBMPlexMono-500.woff2') format('woff2')}

/* ==========================================================================
   Cost Per Use, design system

   DIRECTION: "the meter reading". Somewhere between an itemised utility bill
   and the data page of a broadsheet. Nothing floats, nothing is rounded, and
   there are no cards: structure is carried entirely by rules, the way it is
   on a printed statement. A 2px rule always means "this is the answer". A
   1px rule means "this is a line item".

   Three things are meant to be memorable:
     1. the figure block, a huge metered number over a tick scale
     2. the working, set as a receipt with a subtotal rule
     3. cost bars that live inside the table rather than in a separate chart

   Green means cheaper, oxide red means dearer. Those two colours carry
   meaning on this site and are never used for decoration.
   ========================================================================== */

:root{
  --paper:#F4F2EC;           /* warm newsprint, not white */
  --surface:#FBFAF7;
  --surface-2:#EAE7DE;
  --ink:#16211F;
  --ink-2:#3D4A47;
  --muted:#727F7A;
  --rule:#D8D4C8;
  --rule-strong:#A9A497;
  --accent:#0B5F55;          /* cheaper / house colour */
  --accent-soft:#DCE9E5;
  --oxide:#9C4221;           /* dearer / watch this */
  --oxide-soft:#F0E0D5;
  --serif:'IBM Plex Serif',Georgia,'Times New Roman',serif;
  --sans:'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --measure:66ch;
  --pad:clamp(18px,4vw,34px);
  --grain:.035;
}

@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    --paper:#111614; --surface:#171F1D; --surface-2:#1F2A27;
    --ink:#E9EDE9; --ink-2:#BAC5C0; --muted:#828E89;
    --rule:#2A3532; --rule-strong:#465350;
    --accent:#4FC3AC; --accent-soft:#122B26;
    --oxide:#E0895C; --oxide-soft:#2C1D14;
    --grain:.05;
  }
}
:root[data-theme="dark"]{
  --paper:#111614; --surface:#171F1D; --surface-2:#1F2A27;
  --ink:#E9EDE9; --ink-2:#BAC5C0; --muted:#828E89;
  --rule:#2A3532; --rule-strong:#465350;
  --accent:#4FC3AC; --accent-soft:#122B26;
  --oxide:#E0895C; --oxide-soft:#2C1D14;
  --grain:.05;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--sans);
  font-size:17px;
  line-height:1.62;
  -webkit-font-smoothing:antialiased;
}

/* Paper grain. One 220 byte inline SVG, fixed so it does not travel with
   scroll, which is what stops it reading as a texture image and lets it read
   as the surface the page is printed on. */
body::before{
  content:"";position:fixed;inset:0;z-index:9999;pointer-events:none;
  opacity:var(--grain);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

img,svg{max-width:100%;height:auto}

/* Figures must align in columns. On a site made of numbers this is not a
   nicety, it is the difference between a table and a list. */
.num,td.num,th.num,.figure__value,.receipt,table,.out__value,input{
  font-variant-numeric:tabular-nums}

h1,h2,h3,h4{font-family:var(--serif);font-weight:600;margin:0;text-wrap:balance}
h1{font-size:clamp(2.05rem,4.8vw,3rem);line-height:1.06;letter-spacing:-.022em}
h2{font-size:clamp(1.35rem,2.5vw,1.72rem);line-height:1.2;letter-spacing:-.015em;
   margin:2.5em 0 .55em}
h3{font-family:var(--sans);font-size:1.06rem;font-weight:600;line-height:1.35;
   margin:2em 0 .4em;letter-spacing:-.005em}
p{margin:0 0 1.1em}
a{color:var(--accent);text-decoration-thickness:1px;text-underline-offset:3px}
a:hover{text-decoration-thickness:2px}
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
hr{border:0;border-top:1px solid var(--rule);margin:2.4em 0}

.wrap{max-width:1080px;margin:0 auto;padding:0 var(--pad)}
.col{max-width:var(--measure)}

/* --- masthead ------------------------------------------------------------
   Double rule under the masthead, the way a statement header is ruled off
   from the lines below it. */
.masthead{background:var(--surface);border-bottom:1px solid var(--rule);
  box-shadow:0 3px 0 -2px var(--rule)}
.masthead__in{display:flex;align-items:center;gap:10px 26px;flex-wrap:wrap;
  max-width:1080px;margin:0 auto;padding:15px var(--pad)}
.wordmark{font-family:var(--serif);font-size:1.25rem;font-weight:600;
  color:var(--ink);text-decoration:none;letter-spacing:-.028em;white-space:nowrap}
.wordmark em{font-family:var(--mono);font-style:normal;font-size:.82em;
  font-weight:400;color:var(--accent);letter-spacing:-.02em}
.wordmark:hover{text-decoration:none}
.wordmark:hover em{text-decoration:underline;text-underline-offset:3px}
.nav{display:flex;gap:20px;flex-wrap:wrap;margin-left:auto;font-size:.93rem;line-height:1}
.nav a{color:var(--ink-2);text-decoration:none;padding-bottom:2px;
  border-bottom:1px solid transparent}
.nav a:hover{color:var(--accent);border-bottom-color:var(--accent)}
.nav a[aria-current="page"]{color:var(--ink);border-bottom-color:var(--accent)}

/* --- tariff bar, the live meter reading the whole site is priced from ---- */
/* The bar keeps its OWN dark panel in both themes rather than following
   --surface-2. A halo only reads as light against something darker than
   itself, so on the cream light theme a glow would just look like blurry
   text. Making the strip a fixed dark instrument panel is what lets the
   three numbers behave like backlit signage, and it separates the live
   meter from the page it prices. */
.tariffbar{background:#0C1211;border-bottom:1px solid #05100D;
  font-size:.82rem;color:#93A19C;overflow:hidden;position:relative}
/* A wide, very soft pool of light behind the readings, so the halo sits on
   a lit surface instead of floating on flat black. */
.tariffbar::before{content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(60% 200% at 42% 50%,rgba(79,195,172,.13),transparent 70%)}
.tariffbar__in{max-width:1080px;margin:0 auto;padding:9px var(--pad);
  display:flex;gap:6px 24px;flex-wrap:wrap;align-items:baseline;
  position:relative}
.tariffbar__label{font-family:var(--mono);font-size:.72rem;text-transform:uppercase;
  letter-spacing:.11em;color:#6F7D78}
/* Three shadows, not one: a tight white core, a mid bloom and a wide falloff.
   That layering is what reads as an illuminated face rather than a blur. */
.tariffbar b{font-family:var(--mono);font-weight:500;color:#F2FFFB;
  letter-spacing:.01em;
  text-shadow:0 0 3px rgba(214,255,244,.95),
              0 0 11px rgba(79,195,172,.72),
              0 0 26px rgba(79,195,172,.42),
              0 0 52px rgba(79,195,172,.22)}
.tariffbar a{color:#8FA8A1;text-decoration-color:#3C4B47}
.tariffbar a:hover{color:#CFEFE6}
/* Forced-colours users get a real border instead of a glow they cannot see. */
@media (forced-colors:active){
  .tariffbar::before{display:none}
  .tariffbar b{text-shadow:none;border-bottom:2px solid}
}

main{padding:clamp(30px,5vw,54px) 0 70px}
.lede{font-size:1.15rem;line-height:1.55;color:var(--ink-2);max-width:var(--measure)}
.kicker{font-family:var(--mono);font-size:.73rem;text-transform:uppercase;
  letter-spacing:.13em;color:var(--muted);margin:0 0 .9em}
.crumbs{font-family:var(--mono);font-size:.76rem;color:var(--muted);margin:0 0 1.5em;
  text-transform:uppercase;letter-spacing:.08em}
.crumbs a{color:var(--muted);text-decoration:none}
.crumbs a:hover{color:var(--accent);text-decoration:underline}
.crumbs i{font-style:normal;padding:0 .5em;color:var(--rule-strong)}

/* --- THE FIGURE BLOCK ----------------------------------------------------
   The signature. A metered number sitting over a tick scale, ruled top and
   bottom like the total line on a bill. It deliberately breaks out of the
   text measure to the left on wide screens. */
.figure{position:relative;max-width:var(--measure);margin:1.9em 0 2.2em;
  border-top:2px solid var(--ink);padding-top:15px}
.figure__label{font-family:var(--mono);font-size:.72rem;text-transform:uppercase;
  letter-spacing:.13em;color:var(--muted);display:block;margin-bottom:.3em}
.figure__value{font-family:var(--mono);font-weight:500;
  font-size:clamp(2.4rem,7.5vw,3.6rem);line-height:1;letter-spacing:-.04em;
  color:var(--ink);display:block}
.figure__unit{font-family:var(--sans);font-size:.3em;font-weight:500;
  color:var(--ink-2);letter-spacing:0;margin-left:.55em;white-space:nowrap}
/* the tick scale: a repeating gradient, so it costs nothing and scales */
.figure__scale{height:11px;margin-top:13px;
  background-image:repeating-linear-gradient(to right,
    var(--rule-strong) 0 1px, transparent 1px 100%);
  background-size:11px 100%;
  border-bottom:1px solid var(--rule-strong)}
.figure__note{font-size:.92rem;color:var(--ink-2);margin:.85em 0 0}
.figure--split{display:grid;gap:6px 34px;grid-template-columns:repeat(auto-fit,minmax(170px,1fr))}

/* --- cost table with bars inside the rows -------------------------------- */
.tablewrap{overflow-x:auto;margin:1.7em 0;border-top:2px solid var(--ink);
  border-bottom:2px solid var(--ink)}
table{border-collapse:collapse;width:100%;font-size:.95rem}
caption{text-align:left;font-size:.85rem;color:var(--muted);padding:0 0 .75em;
  max-width:var(--measure)}
th{text-align:left;font-family:var(--mono);font-weight:400;font-size:.71rem;
  text-transform:uppercase;letter-spacing:.11em;color:var(--muted);
  padding:11px 14px 9px;border-bottom:1px solid var(--rule-strong);white-space:nowrap}
td{padding:11px 14px;border-bottom:1px solid var(--rule);vertical-align:middle}
tbody tr:last-child td{border-bottom:0}
tbody tr:hover{background:var(--surface)}
td.num,th.num{text-align:right;font-family:var(--mono);white-space:nowrap}
.rowlabel{font-weight:500}
.rowsub{display:block;font-size:.83rem;color:var(--muted);font-weight:400;line-height:1.4}
.barcell{width:36%;min-width:120px;padding-right:18px}
.bar{display:block;height:9px;background:var(--accent);min-width:2px;
  transform-origin:left center}
.bar--high{background:var(--oxide)}
tr[data-best] .rowlabel::after{content:"cheapest";font-family:var(--mono);
  font-size:.62rem;text-transform:uppercase;letter-spacing:.1em;
  background:var(--accent-soft);color:var(--accent);padding:2px 6px;margin-left:9px;
  vertical-align:2px;font-weight:400}

/* --- THE WORKING, set as a receipt --------------------------------------- */
.receipt{font-family:var(--mono);font-size:.87rem;line-height:1.55;
  background:var(--surface);border:1px solid var(--rule);
  padding:16px 18px;margin:1.7em 0;max-width:var(--measure)}
.receipt__title{font-size:.71rem;text-transform:uppercase;letter-spacing:.13em;
  color:var(--muted);padding-bottom:9px;margin-bottom:10px;
  border-bottom:1px dashed var(--rule-strong)}
.receipt__row{display:flex;gap:14px;align-items:baseline;padding:3px 0}
.receipt__row span:first-child{flex:1 1 auto;color:var(--ink-2)}
/* leader dots, the detail that makes it read as a bill rather than a list */
.receipt__row span:first-child::after{content:"";display:inline-block;width:100%;
  margin-left:.5em;border-bottom:1px dotted var(--rule-strong);
  transform:translateY(-.28em)}
.receipt__row b{font-weight:400;white-space:nowrap;font-variant-numeric:tabular-nums}
.receipt__row--total{border-top:2px solid var(--ink);margin-top:10px;padding-top:9px}
.receipt__row--total span:first-child{color:var(--ink);font-weight:500}
.receipt__row--total b{font-weight:500;color:var(--accent);font-size:1.12em}
.receipt__foot{font-size:.78rem;color:var(--muted);margin-top:11px;line-height:1.5}

/* --- notes and disclosure ------------------------------------------------ */
.note{border-top:1px solid var(--oxide);background:var(--oxide-soft);
  padding:14px 16px;margin:1.7em 0;max-width:var(--measure);font-size:.95rem}
.note p:last-child{margin-bottom:0}
.note__label{font-family:var(--mono);font-size:.7rem;text-transform:uppercase;
  letter-spacing:.13em;color:var(--oxide);display:block;margin-bottom:.45em}
.disclosure{font-size:.85rem;color:var(--muted);border-left:2px solid var(--rule-strong);
  padding:2px 0 2px 13px;margin:1.7em 0;max-width:var(--measure)}

/* --- index lists --------------------------------------------------------- */
.index{border-top:2px solid var(--ink);margin:1.5em 0 0;padding:0;list-style:none}
.index li{border-bottom:1px solid var(--rule)}
.index a{display:grid;grid-template-columns:1fr auto;gap:4px 20px;align-items:baseline;
  padding:16px 0;text-decoration:none;color:var(--ink)}
.index__title{font-family:var(--serif);font-weight:600;font-size:1.1rem;
  line-height:1.25;letter-spacing:-.015em}
.index a:hover .index__title{color:var(--accent);text-decoration:underline;
  text-underline-offset:3px}
.index__desc{grid-column:1/-1;font-size:.93rem;color:var(--ink-2);max-width:62ch;
  line-height:1.5}
.index__meta{font-family:var(--mono);font-size:.72rem;color:var(--muted);
  text-transform:uppercase;letter-spacing:.1em;white-space:nowrap}
.index--empty{color:var(--muted);font-size:.95rem;padding:18px 0;
  border-bottom:1px solid var(--rule);max-width:var(--measure)}

/* --- calculator ---------------------------------------------------------- */
.calc{background:var(--surface);border-top:2px solid var(--ink);
  border-bottom:2px solid var(--ink);margin:2.2em 0;max-width:860px}
.calc__head{padding:15px var(--pad);border-bottom:1px solid var(--rule)}
.calc__head h2{margin:0;font-size:1.15rem}
.calc__head p{margin:.3em 0 0;font-size:.9rem;color:var(--ink-2)}
.calc__body{padding:var(--pad);display:grid;gap:17px;
  grid-template-columns:repeat(auto-fit,minmax(185px,1fr))}
.field{display:flex;flex-direction:column;gap:5px;min-width:0}
.field label{font-family:var(--mono);font-size:.7rem;font-weight:400;color:var(--muted);
  text-transform:uppercase;letter-spacing:.1em}
.field input,.field select{font-family:var(--mono);font-size:.97rem;padding:9px 10px;
  border:1px solid var(--rule-strong);border-radius:0;background:var(--paper);
  color:var(--ink);width:100%}
.field input:focus,.field select:focus{border-color:var(--accent);outline:none;
  box-shadow:inset 0 -2px 0 var(--accent)}
.field small{font-size:.77rem;color:var(--muted);text-transform:none;letter-spacing:0;
  line-height:1.4}
.field--wide{grid-column:1/-1}
.calc__out{border-top:1px solid var(--rule-strong);padding:var(--pad);
  background:var(--surface-2)}
.calc__grid{display:grid;gap:18px;grid-template-columns:repeat(auto-fit,minmax(135px,1fr));
  margin-bottom:16px}
.out{border-top:1px solid var(--rule-strong);padding-top:7px}
.out--lead{border-top:2px solid var(--accent)}
.out__label{font-family:var(--mono);font-size:.69rem;text-transform:uppercase;
  letter-spacing:.11em;color:var(--muted);display:block}
.out__value{font-family:var(--mono);font-weight:500;font-size:1.65rem;line-height:1.2;
  display:block;letter-spacing:-.025em}
.out--lead .out__value{color:var(--accent);font-size:2.15rem}

/* --- affiliate slot, dormant until campaigns exist ----------------------- */
.adslot{margin:2.1em 0;max-width:var(--measure)}
.adslot:empty{display:none}

/* --- sources ------------------------------------------------------------- */
.sources{max-width:var(--measure);margin:2.8em 0 0;padding-top:1.1em;
  border-top:1px solid var(--rule);font-size:.89rem;color:var(--ink-2)}
.sources h2{font-family:var(--mono);font-size:.71rem;font-weight:400;
  text-transform:uppercase;letter-spacing:.13em;color:var(--muted);margin:0 0 .8em}
.sources ul{margin:0;padding-left:1.15em}
.sources li{margin-bottom:.5em}
.checked{font-family:var(--mono);font-size:.77rem;color:var(--muted)}

/* --- footer -------------------------------------------------------------- */
.footer{border-top:1px solid var(--rule);background:var(--surface);margin-top:66px;
  padding:32px 0 48px;font-size:.9rem;color:var(--ink-2);
  box-shadow:0 -3px 0 -2px var(--rule)}
.footer__in{max-width:1080px;margin:0 auto;padding:0 var(--pad);display:grid;gap:24px;
  grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.footer h2{font-family:var(--mono);font-size:.7rem;font-weight:400;text-transform:uppercase;
  letter-spacing:.13em;color:var(--muted);margin:0 0 .7em}
.footer ul{list-style:none;margin:0;padding:0}
.footer li{margin-bottom:.32em}
.footer a{color:var(--ink-2);text-decoration:none}
.footer a:hover{color:var(--accent);text-decoration:underline}
.colophon{max-width:1080px;margin:28px auto 0;padding:17px var(--pad) 0;
  border-top:1px solid var(--rule);font-size:.83rem;color:var(--muted);
  max-width:1080px}
.colophon p{margin:0 0 .4em}

.skip{position:absolute;left:-9999px}
.skip:focus{left:10px;top:10px;z-index:10000;background:var(--surface);padding:10px 15px;
  border:2px solid var(--accent)}

/* --- one orchestrated page load, then nothing ---------------------------- */
@media (prefers-reduced-motion:no-preference){
  .figure,.tablewrap,.receipt{animation:rise .5s cubic-bezier(.2,.7,.3,1) both}
  .tablewrap{animation-delay:.06s}
  .receipt{animation-delay:.12s}
  .bar{animation:sweep .62s cubic-bezier(.2,.7,.3,1) both;animation-delay:.18s}
  @keyframes rise{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
  @keyframes sweep{from{transform:scaleX(0)}to{transform:scaleX(1)}}
}

@media (max-width:560px){
  body{font-size:16px}
  .nav{width:100%;margin-left:0;gap:16px}
  th,td{padding:10px 11px}
  .barcell{display:none}          /* the number survives, the chart does not */
}
@media print{
  body::before,.masthead,.tariffbar,.footer,.adslot,.calc__body{display:none}
  body{background:#fff;color:#000;font-size:11pt}
  .figure,.tablewrap{border-color:#000}
  a{text-decoration:none;color:#000}
}

/* --- grouped table rows --------------------------------------------------
   Rows are only ever ranked against rows measured in the same unit. The
   group header says which unit, so a reader is never invited to compare a
   cost per load with a cost per cup. */
.grouprow th{background:var(--surface-2);border-bottom:1px solid var(--rule-strong);
  border-top:1px solid var(--rule-strong);color:var(--ink);font-size:.7rem;
  letter-spacing:.13em;padding:8px 14px}
tbody:first-of-type .grouprow th{border-top:0}
.nocompare{font-family:var(--mono);font-size:.72rem;color:var(--muted);
  letter-spacing:.04em}

/* --- article layout ------------------------------------------------------
   One reading column plus a rail. The rail exists only to hold the 160x600,
   and it disappears below 1180px rather than squeezing the prose, because a
   cramped measure costs more than a slot is worth. */
.article{display:grid;grid-template-columns:minmax(0,1fr);gap:0}
.article__main{min-width:0}
.rail{display:none}
@media (min-width:1180px){
  .article{grid-template-columns:minmax(0,1fr) 160px;gap:44px}
  .rail{display:block}
  .rail .adslot{position:sticky;top:26px;margin:0}
}

.bullets{max-width:var(--measure);padding-left:1.15em;margin:1.2em 0}
.bullets li{margin-bottom:.6em}

/* --- ad slots ------------------------------------------------------------
   A slot with no campaign emits no element at all, so there is nothing here
   to hide. No house "advertise here" box: on a site with no advertisers it
   advertises only that there are no advertisers, and it spends a reader's
   attention to do it.

   The :empty rule stays as belt and braces for any slot that renders its
   wrapper before its contents.

   Everything below is deliberately quiet. This site's entire proposition is
   that the numbers are honest, and an ad that tries to pass for editorial
   spends exactly the credibility the numbers are there to build. The label
   is always visible, the rule separates it from the prose, and nothing about
   a banner is allowed to look like a figure block. */
.adslot{margin:2.4em 0;max-width:var(--measure);display:flex;flex-direction:column;
  align-items:flex-start;gap:.5em}
.adslot:empty{display:none}
.adslot__label{font-family:var(--mono);font-size:.63rem;text-transform:uppercase;
  letter-spacing:.16em;color:var(--muted);line-height:1;padding-top:.55em;
  border-top:1px solid var(--rule);width:100%}
.adslot .ad{display:block;max-width:100%;line-height:0}
/* Creatives arrive at a fixed pixel size and phones are narrower than the
   smallest of them. Scaling by height keeps the aspect ratio the advertiser
   supplied instead of squashing their artwork. */
.adslot .ad img,.adslot .ad iframe{max-width:100%;height:auto;display:block}

/* The measure is 66ch, about 673px, and a leaderboard creative is 728px. Left
   capped at the measure it was being scaled down 7%, which softens type that
   an advertiser set at exactly the right size. The column is 808px, so the
   one slot wider than the prose is allowed to be. On a narrow viewport the
   parent shrinks first and the image's max-width:100% takes over, so this
   never causes horizontal overflow. */
.adslot--leaderboard{margin:1.9em 0;max-width:728px}
.adslot--sticky{position:fixed;left:0;right:0;bottom:0;z-index:50;
  margin:0;max-width:none;background:var(--surface);border-top:1px solid var(--rule-strong);
  padding:5px 6px;flex-direction:row;align-items:center;justify-content:center;gap:.7em}
/* In the sticky bar the label sits beside the creative, not above it: the bar
   is 50px tall and a stacked label would halve the space the advertiser paid
   for. */
.adslot--sticky .adslot__label{border-top:0;padding-top:0;width:auto;flex:0 0 auto}
/* The bar is fixed over the page, so the last lines of the colophon sat under
   it (2026-09-14, "fix the footer"). When a sticky creative is on the page the
   footer gets the bar's height (50px creative + padding + border) on top of
   its own bottom padding; an empty slot renders nothing, so pages without a
   sticky campaign keep the normal footer. */
body:has(.adslot--sticky) .footer{padding-bottom:116px}

/* --- the two-machine comparison table ------------------------------------ */
td.num.win{color:var(--accent);font-weight:500}
.winner{font-family:var(--mono);font-size:.78rem;color:var(--muted);
  text-transform:uppercase;letter-spacing:.05em;white-space:nowrap}
.minibar{display:flex;flex-direction:column;gap:3px}
.minibar i{display:block;height:7px;background:var(--accent);min-width:2px}
.minibar i.bar--oven{background:var(--rule-strong)}
.minibar i.bar--high{background:var(--oxide)}
.tablekey{font-family:var(--mono);font-size:.72rem;color:var(--muted);
  text-transform:uppercase;letter-spacing:.08em;margin:.7em 0 0;padding:0 14px 10px;
  display:flex;gap:8px;align-items:center}
.key{display:inline-block;width:14px;height:7px;margin-left:14px}
.key--af{background:var(--accent);margin-left:0}
.key--ov{background:var(--rule-strong)}

/* --- FAQ ----------------------------------------------------------------- */
.faq{max-width:var(--measure);border-top:1px solid var(--rule-strong);margin:1.4em 0}
.faq details{border-bottom:1px solid var(--rule)}
.faq summary{cursor:pointer;padding:13px 0;font-weight:500;list-style:none;
  display:flex;justify-content:space-between;gap:14px;align-items:baseline}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font-family:var(--mono);color:var(--accent);
  font-size:1.1rem;line-height:1}
.faq details[open] summary::after{content:"\2212"}
.faq summary:hover{color:var(--accent)}
.faq details p{margin:0 0 15px;color:var(--ink-2);max-width:62ch}

/* --- contact form --------------------------------------------------------
   Same fields and same bounds as the form on hoesenhifi.nl/contact, drawn in
   this site's furniture rather than that one's: the sibling is Tailwind on
   white with rounded corners and a blue focus ring, and this site is warm
   newsprint with square corners and a green one. Copying its palette would
   have put a visitor on a page that looks like somebody else's.

   Reuses .field from the calculator, which already handles the label, the
   input and the focus treatment, so the only new rules are the ones the
   calculator has no use for: a textarea, the two-up row, the sent panel and
   the honeypot.                                                            */
.contact{max-width:var(--measure);margin:1.8em 0 0}
.contact__row{display:grid;gap:17px;grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}
.contact .field{margin:0 0 17px}
.contact__row .field{margin-bottom:0}
.contact__row+.field{margin-top:17px}
.contact textarea{font-family:var(--sans);font-size:.97rem;line-height:1.55;padding:9px 10px;
  border:1px solid var(--rule-strong);border-radius:0;background:var(--paper);
  color:var(--ink);width:100%;resize:vertical}
.contact textarea:focus{border-color:var(--accent);outline:none;
  box-shadow:inset 0 -2px 0 var(--accent)}
.contact__send{font-family:var(--mono);font-size:.8rem;text-transform:uppercase;
  letter-spacing:.11em;padding:12px 22px;border:0;background:var(--accent);
  color:var(--surface);cursor:pointer}
.contact__send:hover{background:var(--ink)}
.contact__send:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.contact__send[disabled]{opacity:.6;cursor:default}
.contact__small{font-size:.82rem;color:var(--muted);margin:1em 0 0;max-width:52ch}
.contact__error{border-left:3px solid var(--oxide);background:var(--oxide-soft);
  color:var(--ink);padding:10px 13px;margin:0 0 1.3em;font-size:.92rem}

/* The thank-you panel. Bordered rather than tinted so it reads as a receipt,
   which is the visual idiom this site already uses for a finished sum. */
.contact__sent{border-top:2px solid var(--accent);border-bottom:1px solid var(--rule);
  background:var(--surface-2);padding:var(--pad)}
.contact__sent:focus{outline:2px solid var(--accent);outline-offset:3px}
.contact__sent p{max-width:56ch}
.contact__sentlead{font-family:var(--serif);font-size:1.3rem;line-height:1.35;margin:0 0 .6em}
.contact__again{font-family:var(--mono);font-size:.76rem;text-transform:uppercase;
  letter-spacing:.11em;margin-top:1.1em;padding:0;border:0;background:none;
  color:var(--accent);cursor:pointer;text-decoration:underline;text-underline-offset:4px}

/* The honeypot. Off-screen rather than display:none, because a form walker
   skipping hidden inputs would never fill it and the trap would catch
   nothing. aria-hidden and tabindex="-1" keep it away from anyone real. */
.contact__trap{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* The click-tracker honeypot in the footer. Same treatment as the contact
   form's trap field: off screen rather than display:none, because a link
   walker that skips hidden elements would never follow it.               */
.cpu-trap{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden;
  color:transparent;text-decoration:none}
