/* ===== PROTON MINING — Public site =====
   Sharp / minimal. Three materials, in this proportion:
     1. Black       — the ground. ~55% of any viewport.
     2. Platinum    — the structure. Type, hairlines, bevels, light.
     3. BTC orange  — the accent. Small area, high value. Never a surface.

   The page is one continuous sheet of metal, lit unevenly. Black is
   the sheet in shadow; platinum is the same sheet catching light. Nothing
   inverts, nothing has a hard edge, and no section owns its own surface —
   brightness just varies across the whole sheet. Platinum shows up four ways:
     - metal-filled type (chrome gradient via background-clip)
     - soft bevel glow on sections and cards
     - structural hairlines
     - the drifting light field itself (see body::before)
   Everything is square: no radii, no soft shadows, no colour bloom. */

:root {
    /* Every form control, scrollbar, caret and autofill on this site renders
       against the system palette unless told otherwise, and the system
       default is light — which is where a stray white field comes from on a
       page that declares none of its own. */
    color-scheme: dark;
    /* --- Black --- */
    --black:     #000000;
    --surface:   #0a0a0a;
    --surface-2: #0e0e0e;

    /* Panel fills — translucent, so the light field shows through. */
    --panel:       rgba(255, 255, 255, 0.015);
    --panel-hover: rgba(255, 255, 255, 0.042);
    --panel-solid: rgba(0, 0, 0, 0.50);

    /* --- Platinum --- */
    --plat-000: #ffffff;
    --plat-100: #efeeec;
    --plat-200: #e5e4e2;  /* platinum */
    --plat-300: #cbcac7;
    --plat-400: #a9a8a5;
    --plat-500: #83827f;
    --plat-600: #5c5b58;

    /* --- BTC orange --- */
    --btc-100: #ffd9a0;
    --btc-200: #ffb347;
    --btc-300: #f7931a;   /* bitcoin */
    --btc-400: #c86f0a;
    --btc-500: #8a4a05;

    /* --- Roles --- */
    /* Semantic state, not a brand colour. Used only on a number below zero,
       and picked for a full 33 degrees of hue separation from the orange
       accent so a loss can never be mistaken for an accent. 5.18:1 on the
       result tiles, above the 4.5:1 small-text bar. */
    --loss:     #e05252;
    --gain:     #3fb950;   /* 7.79:1 on the tiles, 95 deg off the accent */
    --text:     #e8e7e5;
    --text-mid: var(--plat-400);
    --text-dim: #787773;
    --accent:   var(--btc-300);

    /* --- Structural hairlines. Platinum, never white. --- */
    --line:     rgba(229, 228, 226, 0.13);
    --line-mid: rgba(229, 228, 226, 0.24);
    --line-hi:  rgba(229, 228, 226, 0.42);
    --line-btc: rgba(247, 147, 26, 0.36);

    /* --- Metal: chrome for type. The hard dark-to-bright flip near 50%
           is the horizon line that makes it read as metal, not grey. --- */
    --metal-plat: linear-gradient(174deg,
        #ffffff 0%, #dcdbd9 17%, #8e8d8a 39%, #6d6c69 47%,
        #f2f1ef 52%, #ffffff 57%, #c9c8c5 72%, #91908c 88%, #e9e8e6 100%);

    /* Softer chrome for small type, where the full flip reads as noise. */
    --metal-plat-soft: linear-gradient(177deg,
        #ffffff 0%, #e4e3e1 40%, #b3b2af 74%, #d6d5d3 100%);

    /* Diagonal metal for surfaces, rules and borders. */
    --metal-plat-flat: linear-gradient(135deg,
        #5c5b58 0%, #b5b4b1 13%, #ffffff 25%, #d0cfcd 34%,
        #83827f 50%, #e8e7e5 65%, #ffffff 76%, #a2a19e 89%, #6b6a67 100%);

    --metal-btc: linear-gradient(176deg,
        #ffd9a0 0%, #f7931a 28%, #c06a08 48%,
        #f9a132 58%, #ffc46b 80%, #d2780b 100%);
    --metal-btc-flat: linear-gradient(135deg,
        #a85a06 0%, #f7931a 20%, #ffc978 40%,
        #f7931a 56%, #c86f0a 76%, #ffb347 100%);

    /* Chrome for small ORANGE TYPE on a lit panel. --metal-btc-flat bottoms
       out at #a85a06, far too dark to read at 13px, and --metal-btc-btn below
       was floored for the opposite case: dark text on an orange field. This
       one is floored for the text itself. */
    --metal-btc-lit: linear-gradient(150deg,
        #ffcf8a 0%, #f7a02b 26%, #ffdcae 48%,
        #f7a02b 68%, #ffb85c 86%, #f7a02b 100%);

    /* Same metal, floor raised so dark text clears 4.5:1 on every stop. The
       decorative gradient above bottoms out at #a85a06, which is only 3.79:1
       against the label — unreadable at the nav CTA's size. Buttons use this. */
    --metal-btc-btn: linear-gradient(135deg,
        #d4791a 0%, #f7931a 18%, #ffd08a 38%,
        #f7931a 56%, #e07f10 76%, #ffc46b 100%);

    /* Polished edge: a machined bevel catching light along its length. */
    --edge-plat: linear-gradient(90deg,
        transparent 0%, rgba(229,228,226,0.03) 20%,
        rgba(255,255,255,0.19) 50%,
        rgba(229,228,226,0.03) 80%, transparent 100%);
    --edge-plat-short: linear-gradient(90deg,
        rgba(255,255,255,0.17) 0%, rgba(229,228,226,0.05) 45%, transparent 88%);


    --sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Inter, Helvetica, Arial, sans-serif;
    --mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace;

    --max: 1200px;
    --gut: 28px;

    /* The drawings are not illustrations beside the copy — they are the subject
       of their sections — so they get their own measure, wider than the one
       running text needs to stay readable.

       Pulled back from 1720px: at that size the box stood 632px tall on a wide
       screen, which is most of a laptop's viewport height once browser chrome
       is off it, and the drawing read as oversized rather than prominent. */
    --max-dg: 1520px;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* The `hidden` attribute has to actually hide things.

   Its only definition is in the UA stylesheet, so ANY author rule that sets
   display beats it — no extra specificity needed, author origin is simply
   stronger. Three calculator blocks are `display: grid` and are toggled with
   `hidden`, and they stayed on screen: switching to "I have machines" left the
   energy inputs visible, because `.calc-group { display: grid }` quietly
   outranked the attribute.

   !important is the right tool exactly here. Without it this depends on source
   order, and the next `display:` rule anyone adds silently breaks it again. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
}

body {
    position: relative;
    font-family: var(--sans);
    background: var(--black);
    color: var(--text);
    line-height: 1.6;
    font-size: 16px;
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

/* The light field. Four layers on long, deliberately non-harmonic periods
   (1870 / 2630 / 3400px). Because the periods never
   divide into each other, the crests drift continuously down the page and never
   land on a section boundary — the lighting has its own rhythm, unrelated to
   the layout. This is the only thing that varies brightness; sections are
   transparent and simply sit on it. */
body::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -2;
    background-image:
        linear-gradient(101deg,
            transparent 6%,
            rgba(229,228,226,0.028) 20%,
            rgba(229,228,226,0.068) 33%,
            rgba(246,245,243,0.095) 43%,
            rgba(229,228,226,0.044) 55%,
            rgba(229,228,226,0.011) 68%,
            transparent 82%),
        linear-gradient(259deg,
            transparent 12%,
            rgba(229,228,226,0.022) 32%,
            rgba(229,228,226,0.058) 50%,
            rgba(246,245,243,0.082) 60%,
            rgba(229,228,226,0.022) 74%,
            transparent 90%),
        linear-gradient(180deg,
            rgba(229,228,226,0.026) 0%, transparent 24%,
            rgba(229,228,226,0.019) 48%, transparent 72%,
            rgba(229,228,226,0.024) 100%),
        linear-gradient(to right,  rgba(229,228,226,0.018) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(229,228,226,0.018) 1px, transparent 1px);
    background-size: 100% 1870px, 100% 2630px, 100% 3400px, 88px 88px, 88px 88px;
    background-repeat: repeat-y, repeat-y, repeat-y, repeat, repeat;
    pointer-events: none;
}

::selection { background: rgba(247,147,26,0.30); color: #fff; }

a { color: inherit; }

::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--black); }
::-webkit-scrollbar-thumb { background: rgba(229,228,226,0.20); border: 3px solid var(--black); }
::-webkit-scrollbar-thumb:hover { background: rgba(229,228,226,0.38); }

/* ===== Metal type ===== */

.metal-plat, .metal-btc { color: var(--text); }
@supports (-webkit-background-clip: text) or (background-clip: text) {
    .metal-plat, .metal-btc {
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        color: transparent;
    }
    .metal-plat { background-image: var(--metal-plat); }
    .metal-btc  { background-image: var(--metal-btc); }
}

/* ===== Layout ===== */

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

section { position: relative; }

/* Sections carry a soft bevel glow rather than a rule — enough to register a
   change of subject, not enough to cut the sheet into blocks. */
.band { position: relative; padding: 112px 0; }
.band::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 1px;
    background-image: var(--edge-plat);
}
.band--tight { padding: 0 0 80px; }
.band--flush::before { display: none; }

/* ===== Typography ===== */

h1, h2, h3, h4 { font-weight: 600; letter-spacing: -0.028em; line-height: 1.12; }

.eyebrow {
    display: flex;
    align-items: center;
    gap: 12px;
    font-family: var(--mono);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--plat-400);
    margin-bottom: 26px;
}
.eyebrow::before {
    content: '';
    width: 24px;
    height: 2px;
    background-image: var(--metal-btc-flat);
    flex-shrink: 0;
}

.h-display {
    font-size: clamp(40px, 6.6vw, 74px);
    line-height: 1.01;
    letter-spacing: -0.045em;
    color: var(--plat-200);
}
.h-section {
    font-size: clamp(28px, 3.8vw, 44px);
    letter-spacing: -0.036em;
    color: var(--plat-200);
}
.h-card { font-size: 19px; letter-spacing: -0.022em; color: var(--plat-100); }

@supports (-webkit-background-clip: text) or (background-clip: text) {
    .h-display, .h-section {
        background-image: var(--metal-plat);
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        color: transparent;
    }
    /* Small headings get the softer chrome — same material, less noise. */
    .h-card:not(.metal-btc), .track h3, .step h3, .faq summary, .brand-name {
        background-image: var(--metal-plat-soft);
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        color: transparent;
    }
    .brand-name span { -webkit-text-fill-color: var(--plat-400); }
}

.lede {
    font-size: clamp(15.5px, 1.6vw, 18px);
    color: var(--plat-400);
    line-height: 1.68;
    max-width: 62ch;
    letter-spacing: -0.006em;
}

.measure { max-width: 68ch; }
.center { text-align: center; }
.center .eyebrow { justify-content: center; }
.center .lede, .center .measure { margin-left: auto; margin-right: auto; }

p + p { margin-top: 16px; }
.mono { font-family: var(--mono); }
.accent { color: var(--btc-300); text-decoration: none; }
.accent:hover { color: var(--btc-200); }

/* Unfilled facts. Deliberately loud — nothing false should ship by accident. */
.ph {
    color: var(--btc-300);
    -webkit-text-fill-color: var(--btc-300);
    font-family: var(--mono);
    font-size: 0.9em;
    font-weight: 500;
    letter-spacing: -0.02em;
    background: rgba(247, 147, 26, 0.07);
    border-bottom: 1px dashed var(--line-btc);
    padding: 0 4px;
    white-space: nowrap;

    /* And it must not be squeezed, or nowrap just moves the problem. .nav-links
       is a flex row and every item in it shrinks by default, so the CTA was
       being compressed below its own text width — and .btn sets overflow:
       hidden, so the label was clipped at both ends rather than overflowing
       visibly. Clipped symmetric text is precisely what "not centred" looks
       like when the box is too small for it. */
    flex: 0 0 auto;
}

/* ===== Nav ===== */

.nav {
    position: sticky;
    top: 0;
    z-index: 100;
    background: rgba(0, 0, 0, 0.82);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    transition: background 0.25s;
}
.nav::after {
    content: '';
    position: absolute;
    bottom: 0; left: 0; right: 0;
    height: 1px;
    background-image: var(--edge-plat);
}
.nav.is-stuck { background: rgba(0, 0, 0, 0.95); }

.nav-inner {
    max-width: var(--max);
    margin: 0 auto;
    padding: 0 var(--gut);
    height: 68px;
    display: flex;
    align-items: center;
    gap: 32px;
}

.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; flex-shrink: 0; }
.brand svg { display: block; }
.brand-name {
    font-size: 13px;
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--plat-200);
}
.brand-name span { color: var(--plat-400); font-weight: 500; }

.nav-links { display: flex; align-items: center; gap: 2px; margin-left: auto; }
.nav-links a {
    padding: 9px 15px;
    /* A nav label that wraps is a nav that has changed height, and this row is
       a fixed bar. The items are flex children, so without this they shrink and
       break mid-phrase — "Energy Partners" and "How We Operate" both did, the
       moment the CTA stopped giving up its own width to make room. Measured at
       1400px the row needs 966px of a 1006px budget, so nothing has to wrap;
       it was only wrapping because it was allowed to. */
    white-space: nowrap;
    font-size: 13.5px;
    letter-spacing: -0.005em;
    color: var(--plat-400);
    text-decoration: none;
    transition: color 0.18s;
    position: relative;
}
.nav-links a:hover { color: var(--plat-000); }
.nav-links a.active { color: var(--plat-100); }
.nav-links a.active::after {
    content: '';
    position: absolute;
    left: 15px; right: 15px; bottom: -1px;
    height: 2px;
    background-image: var(--metal-btc-flat);
    z-index: 1;
}
.nav-cta { margin-left: 14px; }
.nav-links a.nav-cta::after { display: none; }

/* The CTA is an <a> inside .nav-links, so ".nav-links a" (0,1,1) outranks
   ".btn--primary" (0,1,0) and the nav's own link colour was winning: the button
   rendered --plat-400 grey on orange, and --plat-000 white on hover. Both of
   those are the unreadable case. This has to be at least (0,2,1) to land. */
.nav-links a.nav-cta,
.nav-links a.nav-cta:hover,
.nav-links a.nav-cta:focus-visible { color: #000000; }

/* THE SAME CLASH AS ABOVE, AND ONLY HALF OF IT WAS EVER FIXED. ".nav-links a"
   (0,1,1) outranks .btn and .btn--sm (0,1,0), so it takes the CTA padding as
   well as its colour, and .btn--sm padding never applied here at all.

   ONLY THE PADDING IS RESTATED. An earlier version of this rule also forced
   .btn--sm font-size (11px) and letter-spacing (0.12em) back on, which was
   correct by the stylesheet and wrong on the page: the label dropped two and a
   half points, leaving the same box around much smaller type, and the button
   read as thick and hollow. The nav own 13.5px is the size this button has
   always been drawn at and is the size it keeps.

   Positive tracking also puts a trailing space after the final letter that is
   inside the text box but not visible, so centred text sits half a space left
   of where it looks like it should. At the nav own -0.005em that is nothing.
   At 0.12em it is a pixel and a third, which is exactly the amount the button
   looked wrong by. */
.nav-links a.nav-cta {
    /* 15px, not the .btn--sm 18px. The nav is exactly full at 1400px — 878 of
       918 used — and at 18px this button needs 4.5px more than the row has, so
       it was being shrunk below its own text and clipped at both ends by the
       overflow:hidden on .btn. Clipped-but-symmetric is what "not centred"
       looks like when the box is too small. */
    /* 9 top, 7 bottom. The label is all-caps and has no descenders, but the
       font reserves descender space below the baseline regardless, so centring
       the line box leaves the letters riding about 1.6px high in a button this
       size. Moving one pixel of padding from the bottom to the top centres the
       CAPS, which is what an eye measures. Same total, same height. */
    padding: 9px 15px 7px;

    /* And it must not be squeezed again. .nav-links is a flex row, every item
       in it shrinks by default, and a CTA that gives up width silently is how
       the clipping happened in the first place. */
    flex-shrink: 0;

    /* THIS IS THE LINE THAT WAS ACTUALLY MISSING.

       The label was wrapping onto two lines. "Start a conversation" is the
       longest CTA on the site, .btn does not set white-space and neither does
       .nav-links a, so the button grew to 59px — two line boxes — and the text
       inside a two-line centred flex box does not look centred, because it is
       not: the second line is a different width from the first.

       That is the whole reported fault. Too thick and not centred were one
       cause, not two.

       It hid behind a font swap. With the fallback face the label fits on one
       line and everything measures correctly; the wrap only appears once the
       real face loads, which is after most measurements are taken and after a
       screenshot is usually captured. Measure this one behind document.fonts.
       ready or it will tell you it is fine. */
    white-space: nowrap;
}

.nav-toggle {
    display: none;
    margin-left: auto;
    width: 40px;
    height: 40px;
    cursor: pointer;
    align-items: center;
    justify-content: center;
    color: var(--plat-200);
    border: 1px solid transparent;
    background:
        linear-gradient(var(--panel-solid), var(--panel-solid)) padding-box,
        var(--metal-plat-flat) border-box;
}

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

.btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 14px 26px;
    font-family: var(--sans);
    font-size: 11.5px;
    font-weight: 650;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    border: 1px solid transparent;
    cursor: pointer;
    overflow: hidden;
    transition: color 0.2s, border-color 0.2s, background 0.2s;
}

/* Brushed sheen that sweeps across on hover. */
.btn::after {
    content: '';
    position: absolute;
    top: 0; left: -130%;
    width: 55%; height: 100%;
    background: linear-gradient(100deg, transparent, rgba(255,255,255,0.42), transparent);
    transform: skewX(-18deg);
    transition: left 0.55s cubic-bezier(0.3, 0, 0.2, 1);
    pointer-events: none;
}
.btn:hover::after { left: 145%; }

.btn--primary {
    background-image: var(--metal-btc-btn);
    /* Black rather than the near-black it was: at the nav CTA's 11px it reads
       as more definitely dark against the metal, and it can only help the
       contrast figure. */
    color: #000000;
    border-color: rgba(255, 210, 150, 0.45);
}
.btn--primary:hover { border-color: rgba(255, 225, 185, 0.8); }

/* Solid platinum border, machined rather than a flat grey line. */
.btn--ghost {
    background:
        linear-gradient(var(--panel-solid), var(--panel-solid)) padding-box,
        var(--metal-plat-flat) border-box;
    color: var(--plat-100);
}
.btn--ghost:hover { color: var(--plat-000); }
.btn--ghost::after { background: linear-gradient(100deg, transparent, rgba(255,255,255,0.28), transparent); }

.btn--sm { padding: 10px 18px; font-size: 11px; letter-spacing: 0.12em; }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 40px; }
.center .btn-row { justify-content: center; }

/* The second audience for a page whose buttons serve the first.

   Hosting's hero now leads to the catalogue, which is right for someone who has not bought
   machines yet and useless to someone whose machines are already crated. This is their route,
   set as a line of text rather than a third button — a hero with three primary-looking
   choices is one a reader makes none of. */
.hero-alt {
    margin: 18px 0 0;
    font-size: 13px;
    color: var(--plat-500);
}
.hero-alt a { color: var(--plat-300); text-underline-offset: 3px; }
.hero-alt a:hover { color: var(--btc-300); }

.arrow-link {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    color: var(--btc-300);
    text-decoration: none;
    font-family: var(--mono);
    font-size: 11.5px;
    font-weight: 500;
    letter-spacing: 0.13em;
    text-transform: uppercase;
    transition: color 0.2s;
}
.arrow-link svg { transition: transform 0.24s cubic-bezier(0.3, 0, 0.2, 1); }
.arrow-link:hover { color: var(--btc-200); }
.arrow-link:hover svg { transform: translateX(4px); }

/* ===== Hero ===== */

.hero { padding: 132px 0 104px; }

/* The energy field is a BACKDROP: it fills whatever box it is dropped into,
   behind the content. data-w / data-h are now only the fallback size for a box
   that is not laid out yet — hero-anim.js measures the real one, because a
   fixed size stretched to fill turned every 1px particle into a 2-3px smear.

   ONE OPACITY, ALL THIRTEEN. This used to be three values: 0.60 on the hero,
   0.55 behind the drawings, 0.85 on the headers, each argued for separately.
   (The hero's was 0.35 for most of its life and had just been raised to 0.60
   when the lattice still needed holding back — the number that shipped is the
   one that matters here.) They are one value because the fields are now one
   animation: the lattice is gone from the hero and from the seven drawing
   backdrops, so there is no longer a busier field needing to be held back, and
   "all the backgrounds look the same" is not achievable while three selectors
   disagree about brightness.

   The modifier classes below still exist and no longer carry any style. They
   are markers for what a canvas sits behind, and pad-suite.js and hero-suite.js
   both identify canvases by them. */
.anim-field {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    pointer-events: none;
    z-index: 0;
    opacity: 0.85;
}
/* WHERE 0.85 CAME FROM. The portal's sign-in field is the reference the whole
   look was tuned against: its canvas is undimmed and its scrim clears to
   rgba(0,0,0,0.12) at the edges, so a producer signing in sees the rise at
   roughly 0.88. Anything much below that and the site reads dimmer than the
   page a counterparty lands on from it.

   WHAT IT COSTS BEHIND THE DRAWINGS, which is where 0.85 was expected to be too
   hot and measurably is not. The worry is real in form: a drawing's faintest
   STROKE is rgba(229,228,226,0.13) at 0.5px — its faintest ink of any kind is
   .dg-ground's 0.04 fill — translucent light laid over whatever the field
   leaves underneath, so lifting the ground under it should cost contrast.

   Measured off the canvas's own pixels across the band the drawing occupies —
   not derived from the alphas, which is what made it look dangerous. Coverage is
   0.063%: 292 inked pixels in 463,450. The field is a few hundred 1-2px marks,
   not a wash, so 99.94% of every hairline sits on untouched ground. On the
   fraction that is touched, the hairline's contrast against its own local ground
   goes UP, 1.300 to 1.377, because stroke and ground rise together and the ratio
   is dominated by the +0.05 floor at near-black.

   Re-measure before lowering this on legibility grounds. The instinct is right
   and the arithmetic is wrong. */

/* .hero already lifts its .wrap; .hero-zone did not, because until now nothing
   was ever painted behind one. The canvas is position:absolute and therefore
   paints above non-positioned content whatever the source order says, so
   without this the field lays over the headline on hardware and calculator. */
.hero-zone > .wrap { position: relative; z-index: 1; }

/* The hero headline is the longest on the site — “Your machines or ours.” is
   9.35em — and the shared clamp floors at 40px, which needs 374px of measure
   in the 320px a 360px phone has. It would wrap to four lines and read as a
   mistake. Only the floor moves; the vw slope and the cap stay shared, so the
   headline is identical to the other pages’ everywhere above ~455px. */
.hero .h-display { font-size: clamp(30px, 6.6vw, 74px); }

/* The hero and the stats strip under one backdrop. The canvas measures against
   this, so the flame covers both and its source line lands on the bottom of the
   pair. Everything after the canvas in document order is positioned, so it
   paints above it without needing a z-index of its own. */
.hero-zone { position: relative; }

/* The flame’s source line now sits on the bottom of the zone, which is exactly
   where the next band draws its top bevel. Two rules on the same pixel is the
   doubled edge this was meant to remove, so the bevel gives way to the flame. */
.hero-zone + .band::before { display: none; }

.hero { position: relative; }
.hero .wrap { position: relative; z-index: 1; }






/* The drawing has to sit above its own backdrop: an absolutely positioned
   canvas otherwise paints over static siblings in the same stacking context. */
.site-diagram { position: relative; z-index: 1; }
.hero .lede { margin-top: 30px; }

.hero-note {
    position: relative;
    margin-top: 40px;
    padding-top: 26px;
    font-size: 13.5px;
    color: var(--text-dim);
    max-width: 58ch;
    letter-spacing: -0.004em;
}
.hero-note::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 1px;
    background-image: var(--edge-plat-short);
}

/* ===== Stat strip — a lit platinum plate ===== */

.stats {
    position: relative;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1px;
    background: var(--line-mid);
    border: 1px solid var(--line-mid);
}
.stats::before {
    content: '';
    position: absolute;
    top: -1px; left: 0; right: 0;
    height: 1px;
    background-image: var(--edge-plat);
    z-index: 2;
}
.stat {
    position: relative;
    padding: 32px 28px;
    background-color: var(--panel);
    background-image: linear-gradient(163deg, rgba(229,228,226,0.055), transparent 62%);
}
.stat-value {
    font-family: var(--mono);
    font-size: clamp(24px, 2.8vw, 34px);
    font-weight: 600;
    letter-spacing: -0.045em;
    line-height: 1.05;
    background-image: var(--metal-btc);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--btc-300);
}
.stat-label {
    margin-top: 12px;
    font-size: 12px;
    color: var(--plat-400);
    letter-spacing: 0.01em;
    line-height: 1.5;
}

/* ===== Grids & cards ===== */

.grid { display: grid; gap: 24px; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

/* Matrix: cards share hairlines instead of floating apart. */
.grid--matrix {
    position: relative;
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
}
.grid--matrix::before {
    content: '';
    position: absolute;
    top: -1px; left: 0; right: 0;
    height: 1px;
    background-image: var(--edge-plat);
    z-index: 2;
}
.grid--matrix > .card { background: var(--panel); border: none; }
.grid--matrix > .card::before { display: none; }
.grid--matrix > .card:hover { background: var(--panel-hover); }

.card {
    position: relative;
    background: var(--panel);
    border: 1px solid var(--line);
    padding: 34px 30px;
    transition: background 0.24s, border-color 0.24s;
}
.card::before {
    content: '';
    position: absolute;
    top: -1px; left: -1px; right: -1px;
    height: 1px;
    background-image: var(--edge-plat);
}
.card--hover:hover { border-color: var(--line-mid); background: var(--panel-hover); }

/* ---- prepaid electricity tiers ----
   Three cards, the middle-length one is not the hero: the LONGEST term is, because that is the
   one with the best rate and the one the ladder exists to sell. Same square corners and same
   accent as everything else — the reference this is modelled on uses a rounded yellow card,
   and this site has neither rounded corners nor yellow. */
.pp-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 20px;
}
.pp-tier {
    border: 1px solid var(--line);
    background: var(--panel);
    display: flex;
    flex-direction: column;
}
/* The best-value tier carries the accent, and carries it on the HEADER rather than as a border
   round the whole card, so three cards side by side still read as one set. */
.pp-tier--best { border-color: var(--line-btc); }
.pp-head {
    background: var(--panel-solid);
    border-bottom: 1px solid var(--line);
    padding: 13px 20px;
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--plat-300);
    text-align: center;
}
.pp-tier--best .pp-head {
    background-image: var(--metal-btc-btn);
    border-bottom-color: var(--line-btc);
    color: var(--black);
}
.pp-body { padding: 24px 22px 26px; display: flex; flex-direction: column; flex: 1; }
.pp-pct {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--plat-500);
    text-align: center;
}
.pp-rate {
    font-size: 27px;
    color: var(--plat-100);
    text-align: center;
    margin-top: 14px;
    font-variant-numeric: tabular-nums;
    letter-spacing: -0.015em;
}
.pp-tier--best .pp-rate { color: var(--btc-300); }
/* A from-price with nothing attached is the oldest trick in pricing; this one names the site. */
.pp-from {
    font-size: 11px;
    color: var(--plat-600);
    text-align: center;
    margin-top: 6px;
    line-height: 1.5;
}
.pp-list { list-style: none; margin: 22px 0 0; padding: 0; }
.pp-list li {
    position: relative;
    padding-left: 20px;
    margin-bottom: 10px;
    font-size: 13px;
    color: var(--plat-400);
}
.pp-list li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 8px;
    width: 9px;
    height: 1px;
    background: var(--btc-300);
}
/* Pushed to the bottom so the buttons line up across cards with different numbers of lines. */
.pp-body .btn { margin-top: auto; justify-content: center; }

/* ---- the ladder on the catalogue page ----
   Same tiers, but each one is a BUTTON here rather than a card with a link in it: on this page
   the tier is a choice that sticks, not a signpost to somewhere else. */
.pp-sec {
    border: 1px solid var(--line);
    background: var(--panel);
    padding: 26px 26px 22px;
    margin-bottom: 30px;
}
.pp-sec-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 16px; margin-bottom: 20px;
}
.pp-sec-eyebrow {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--btc-300); margin-bottom: 6px;
}
.pp-sec-title { font-size: 19px; color: var(--plat-100); }
.pp-clear {
    background: none; border: 1px solid var(--line-mid); color: var(--plat-400);
    border-radius: var(--radius); font: inherit; font-size: 11.5px; padding: 7px 12px;
    cursor: pointer; white-space: nowrap; flex-shrink: 0;
}
.pp-clear:hover { border-color: var(--line-btc); color: var(--plat-200); }

button.pp-tier--pick {
    display: flex; flex-direction: column; text-align: left;
    font: inherit; cursor: pointer; padding: 0;
    background: var(--panel); border: 1px solid var(--line);
    border-radius: var(--radius);
}
button.pp-tier--pick .pp-head { display: block; }
button.pp-tier--pick .pp-body { display: flex; flex-direction: column; flex: 1; padding: 20px 18px 0; }
button.pp-tier--pick:hover { border-color: var(--line-mid); }
/* SELECTED IS A BORDER AND A LABEL, not colour alone. Which term is chosen decides what a
   customer pays for seven years, and a reader who cannot separate two oranges has to be able to
   see it as clearly as anyone else. */
button.pp-tier--pick.is-on { border-color: var(--btc-300); background: var(--panel-hover); }

.pp-total {
    margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--line);
    font-size: 14px; color: var(--plat-200); line-height: 1.5;
}
.pp-saved { font-size: 12px; color: var(--btc-300); }
.pp-total--empty { color: var(--plat-500); font-size: 12px; }

.pp-pick {
    display: block; margin-top: 16px; padding: 11px 18px;
    border-top: 1px solid var(--line);
    font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--plat-400); text-align: center;
}
button.pp-tier--pick.is-on .pp-pick { color: var(--btc-300); }
button.pp-tier--pick:hover .pp-pick { color: var(--plat-200); }

.pp-note { margin: 18px 0 0; font-size: 11.5px; color: var(--plat-500); line-height: 1.6; }

/* The chosen term, restated in the cart. It sits inside the facility block because it is part of
   the same decision — which site, on what terms — and because this is the last screen before
   the order is sent. */
.fac-prepay {
    margin-top: 14px; padding-top: 13px; border-top: 1px solid var(--line);
    font-size: 13px; color: var(--plat-300); line-height: 1.6;
}
.fac-prepay strong { color: var(--btc-300); }
.fac-prepay-note { font-size: 11.5px; color: var(--plat-500); }

/* THE FACILITY GRID IS SIZED BY WIDTH, NOT BY COUNT.

   It was .grid-4, which is fine for four sites and orphans the fifth on a row of its own the
   moment one is added — and the number of sites is exactly the thing that changes. auto-fit
   with a floor lets the row hold as many as fit: five across at the full 1144px measure, three
   on a tablet, one on a phone, without anybody editing a column count when a site opens.

   The gap is tighter than the site default for the same reason: at 24px the fifth card does not
   fit, and 16px is the difference between one row and a widow. */
.fac-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 16px;
}

/* ---- long-form reading ----

   The site had no prose styles: every page until now was headings, cards and tables, so a run
   of paragraphs had nothing holding it. Three things carry a body of text and the rest is
   decoration:

   MEASURE. Running text sits at 68 characters. Wider and the eye loses the line return; the
   wrap below is the only place on the site that constrains width for reading rather than for
   layout.
   RHYTHM. Space between blocks comes from one scale, and headings take more space above than
   below so a heading belongs to what follows it rather than floating between two sections.
   CONTRAST. Body copy is --plat-200 rather than the --plat-500 used for captions elsewhere.
   Caption grey is legible in a two-line label and exhausting over a thousand words. */

.wrap--narrow { max-width: 720px; }

.bp { padding: 56px 0 88px; }
.bp h1 {
    font-size: clamp(30px, 4.2vw, 46px); line-height: 1.12; letter-spacing: -0.02em;
    margin: 0 0 18px; text-wrap: balance;
}
.bp .lede { margin-bottom: 26px; }

.bp-meta {
    display: flex; align-items: baseline; gap: 16px; flex-wrap: wrap;
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--plat-500); margin-bottom: 22px;
}
.bp-back { color: var(--btc-300); }
.bp-back:hover { opacity: 0.78; }
.bp-date, .bp-read { position: relative; }
.bp-read::before {
    content: ''; position: absolute; left: -9px; top: 50%;
    width: 2px; height: 2px; background: var(--plat-500);
}

.bp-tags { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 30px; }
.bp-tag {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em;
    text-transform: uppercase; color: var(--plat-500);
    border: 1px solid var(--line-mid); padding: 4px 9px;
}

/* ---- the body itself ---- */

.bp-body { max-width: 68ch; }
.bp-body > * + * { margin-top: 20px; }
.bp-body p { font-size: 16px; line-height: 1.72; color: var(--plat-200); }
.bp-body h2 {
    font-size: 23px; line-height: 1.25; letter-spacing: -0.01em;
    margin-top: 46px; text-wrap: balance;
}
.bp-body h3 { font-size: 18px; line-height: 1.3; margin-top: 34px; }
.bp-body h4 { font-size: 15px; margin-top: 28px; color: var(--plat-200); }
.bp-body strong { color: var(--plat-100); font-weight: 600; }
.bp-body em { color: var(--plat-100); font-style: italic; }

.bp-body a {
    color: var(--btc-300);
    border-bottom: 1px solid rgba(247, 147, 26, 0.32);
    padding-bottom: 1px;
}
.bp-body a:hover { border-bottom-color: var(--btc-300); }

.bp-body ul, .bp-body ol { padding-left: 22px; display: grid; gap: 9px; }
.bp-body li { font-size: 16px; line-height: 1.68; color: var(--plat-200); }
.bp-body li::marker { color: var(--plat-500); }

/* A quote is set off by a rule and a shift in colour, not by italics: a long italic passage is
   harder to read than the thing it is quoting. */
.bp-body blockquote {
    border-left: 2px solid var(--btc-300);
    padding: 2px 0 2px 20px;
    font-size: 16px; line-height: 1.7; color: var(--plat-100);
}

.bp-body code {
    font-family: var(--mono); font-size: 0.88em;
    background: rgba(229, 228, 226, 0.07); padding: 2px 5px;
    color: var(--plat-100);
}
.bp-code {
    /* Its own scroller, so a long line moves inside the block instead of the page. */
    overflow-x: auto; background: #0b0b0b; border: 1px solid var(--line-mid);
    padding: 16px 18px; font-size: 13px; line-height: 1.6;
}
.bp-code code { background: none; padding: 0; font-size: inherit; }

.bp-body hr { border: none; border-top: 1px solid var(--line-mid); margin: 40px 0; }

/* ---- draft banner ----
   Loud on purpose. Somebody sent this link expecting the live page, and the one thing they
   must not do is quote a draft back at a customer. */
.bp-draft {
    border: 1px solid var(--btc-300);
    background: rgba(247, 147, 26, 0.07);
    padding: 13px 16px; margin-bottom: 26px;
    font-size: 13px; line-height: 1.6; color: var(--plat-100);
}
.bp-draft strong { color: var(--btc-300); }
.bp-draft code { font-family: var(--mono); font-size: 12px; color: var(--plat-100); }

/* ---- sources ----
   Every factual claim in a post carries one. They are set small but not hidden: a post whose
   sources are hard to find is a post asking to be taken on trust. */
.bp-sources { margin-top: 52px; padding-top: 24px; border-top: 1px solid var(--line-mid); }
.bp-sources h2 {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--plat-500); margin: 0 0 12px;
}
.bp-sources ol { padding-left: 18px; display: grid; gap: 7px; }
.bp-sources li { font-size: 12.5px; line-height: 1.55; word-break: break-word; }
.bp-sources a { color: var(--plat-500); }
.bp-sources a:hover { color: var(--btc-300); }

.bp-next { margin-top: 52px; padding-top: 28px; border-top: 1px solid var(--line-mid); }
.bp-next h2 { font-size: 19px; margin: 0 0 8px; text-wrap: balance; }
.bp-next p { font-size: 14px; line-height: 1.65; color: var(--plat-500); max-width: 60ch; }
.bp-next-links { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 18px; }

/* ---- calculator: what it models ----
   A crawler stripped this page to 778 words, nearly all form labels. This section is the part
   of the page that is actually readable, so it is set as prose rather than as chrome. */
.calc-strap {
    font-family: var(--mono); font-size: 12px; letter-spacing: 0.12em;
    text-transform: uppercase; color: var(--btc-300); margin: 14px 0 18px;
}
.calc-models { margin-top: 56px; padding-top: 34px; border-top: 1px solid var(--line-mid); }
.calc-models-lede {
    font-size: 16px; line-height: 1.7; color: var(--plat-200);
    max-width: 64ch; margin: 14px 0 30px;
}
.calc-models-grid {
    display: grid; gap: 1px; background: var(--line);
    border: 1px solid var(--line-mid);
    grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
}
.cm { background: var(--black); padding: 22px 24px; display: grid; gap: 9px; align-content: start; }
.cm h3 { font-size: 16px; line-height: 1.3; margin: 0; color: var(--plat-100); text-wrap: balance; }
.cm p { font-size: 14px; line-height: 1.62; color: var(--plat-500); margin: 0; }
.calc-models-foot {
    margin-top: 22px; font-size: 14px; line-height: 1.65;
    color: var(--plat-500); max-width: 66ch;
}

/* ---- read next ----
   Post to post, which is the link direction that tells a crawler these pages are about the
   same subject. Shared tags decide the order, not recency. */
.bp-rel { margin-top: 52px; padding-top: 24px; border-top: 1px solid var(--line-mid); }
.bp-rel-head {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--plat-500); margin-bottom: 14px;
}
.bp-rel-item {
    display: grid; gap: 4px; padding: 14px 0;
    border-top: 1px solid var(--line);
}
.bp-rel-item:first-of-type { border-top: none; }
.bp-rel-title { font-size: 16px; line-height: 1.35; color: var(--plat-100); }
.bp-rel-sum { font-size: 13px; line-height: 1.55; color: var(--plat-500); }
.bp-rel-item:hover .bp-rel-title { color: var(--btc-300); }

/* ---- the index ---- */

.bl-grid {
    display: grid; gap: 1px; margin-top: 36px;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    background: var(--line);
    border: 1px solid var(--line-mid);
}
/* One border between cards rather than a border each: the grid gap shows the ground through,
   which is how the facility cards are built and keeps the two grids consistent. */
.bc {
    background: var(--black); padding: 24px 24px 22px;
    display: flex; flex-direction: column; gap: 10px;
    transition: background 0.18s ease;
}
.bc:hover { background: #0b0b0b; }
.bc-top {
    display: flex; justify-content: space-between; gap: 12px;
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.12em;
    text-transform: uppercase; color: var(--plat-500);
}
.bc-title {
    font-size: 19px; line-height: 1.25; margin: 0; color: var(--plat-100);
    text-wrap: balance;
}
.bc-sum { font-size: 13.5px; line-height: 1.6; color: var(--plat-500); margin: 0; flex: 1; }
.bc-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.bc-go {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--btc-300); margin-top: 4px;
}
.bc:hover .bc-go { opacity: 0.82; }

.bl-foot { margin-top: 44px; padding-top: 28px; border-top: 1px solid var(--line-mid); }
.bl-foot h2 { font-size: 20px; margin: 0 0 8px; }
.bl-foot p { font-size: 14px; line-height: 1.65; color: var(--plat-500); max-width: 58ch; }
.bl-foot .btn { margin-top: 16px; }

@media (max-width: 560px) {
    .bp { padding: 40px 0 64px; }
    .bp-body h2 { margin-top: 36px; }
}

/* ---- why-mining: the argument page ----

   Reuses the prose scale above rather than inventing a second one. What is specific here is
   that the page makes CONDITIONAL claims, and the conditions have to carry the same weight as
   the claims or the page becomes an advertisement with small print. So a mechanism is a claim
   line followed by a definition list of conditions set at the same size, not a paragraph with
   caveats trailing off the end of it. */

/* THE PROSE IS NARROW; THE PAGE IS NOT.
 *
 * This was `max-width: 760px` on the whole block, which capped the structured grids as well as
 * the sentences. `.wm-mechs` is a grid with no `grid-template-columns` — so three mechanism
 * cards stacked one above another inside a 760px column while 440px of the 1200px wrap sat
 * empty beside them. That single fact was most of the scrolling complaint: the page was long
 * because it was narrow, not because it was wordy.
 *
 * So the block is full width and the RUNNING TEXT is capped instead. Sentences stay at ~64
 * characters, where the eye reliably finds the next line; grids and callouts take the width
 * they were designed for. The h2 keeps its full-width border-top, which now reads as a proper
 * section rule rather than a line that stops two-thirds of the way across. */
.wm-body { max-width: none; }
.wm-body > * + * { margin-top: 22px; }
.wm-body > p, .wm-body > ul, .wm-body > h3 { max-width: 64ch; }

/* Anchors land below the fixed nav instead of under it. Needed now that the answer block at
   the top jumps into the page — before that there were no fragment links here at all. */
.wm-body h2[id], .wm-body h3[id] { scroll-margin-top: 84px; }

/* ---- the notes rail ----

   The Learn page runs a 64ch text column inside a 1200px wrap, so there is a permanent empty
   gutter beside it. Recent posts go there: it uses space that was doing nothing, and it adds
   the internal link direction the site was missing — posts already pointed at this page, and
   this page pointed at no post.

   IT ONLY APPEARS WHERE IT FITS. Below 1180px the content column would have to give up width
   the mechanism grid needs, so the rail stops being a rail and becomes a normal block after
   the argument. A sidebar that squeezes the thing it sits beside is not using spare space, it
   is taking space.

   STICKY, NOT FIXED. It scrolls with the page until it reaches the top, then holds — so it is
   there when you want it and never covers anything. */
.wm-layout { display: block; }

.wm-rail {
    margin-top: 40px; padding-top: 20px;
    border-top: 1px solid var(--line-mid);
}
.wm-rail-head {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--btc-300); margin-bottom: 12px;
}
.wm-rail-item {
    display: grid; gap: 3px; padding: 11px 0;
    border-top: 1px solid var(--line);
}
.wm-rail-item:first-of-type { border-top: none; }
.wm-rail-date {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--plat-500);
}
.wm-rail-title {
    font-size: 14px; line-height: 1.4; color: var(--plat-200);
}
.wm-rail-item:hover .wm-rail-title { color: var(--plat-000); }
.wm-rail-all {
    display: inline-block; margin-top: 14px;
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--btc-300);
}
.wm-rail-all:hover { opacity: 0.78; }
.wm-rail-empty { font-size: 13px; color: var(--plat-500); }


/* ---- the answer, before the argument ----
   Two cells, one per question, each with the conclusion and a way in. A reader who already
   knows what they think can leave from here, which is a feature. */
.wm-tldr {
    display: grid; gap: 1px; background: var(--line);
    border: 1px solid var(--line-mid);
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.wm-tldr-cell { background: var(--black); padding: 22px 24px; display: grid; gap: 10px;
                align-content: start; }
.wm-tldr-k {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--btc-300); margin: 0;
}
.wm-tldr-cell p { font-size: 15px !important; line-height: 1.6 !important; max-width: none; }
.wm-tldr-go { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: 2px; }
/* Links look like links. A jump dressed as a button implies it goes somewhere else. */
.wm-tldr-go a { font-size: 13px; }

/* ---- the comparison, read across instead of down ---- */
.wm-vs {
    display: grid; gap: 1px; background: var(--line);
    border: 1px solid var(--line-mid);
    grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
}
.wm-vs-col { background: var(--black); padding: 22px 24px; }
.wm-vs-col h3 { margin: 0 0 14px; font-size: 17px; max-width: none; }
.wm-vs-col ul { padding-left: 18px; display: grid; gap: 10px; max-width: none; }
.wm-vs-col li { font-size: 14.5px; line-height: 1.6; }
.wm-body p { font-size: 16px; line-height: 1.72; color: var(--plat-200); }
.wm-body h2 {
    font-size: 26px; line-height: 1.2; letter-spacing: -0.015em;
    margin-top: 58px; padding-top: 26px; border-top: 1px solid var(--line-mid);
    text-wrap: balance;
}
.wm-body h3 { font-size: 19px; line-height: 1.3; margin-top: 40px; text-wrap: balance; }
.wm-body h4 { font-size: 16px; margin: 0 0 8px; color: var(--plat-100); }
.wm-body strong { color: var(--plat-100); font-weight: 600; }
.wm-body em { color: var(--plat-100); font-style: italic; }
.wm-body ul { padding-left: 20px; display: grid; gap: 11px; }
.wm-body li { font-size: 16px; line-height: 1.65; color: var(--plat-200); }
.wm-body li::marker { color: var(--plat-500); }
.wm-body a:not(.btn) { color: var(--btc-300); border-bottom: 1px solid rgba(247,147,26,0.32); }
.wm-body a:not(.btn):hover { border-bottom-color: var(--btc-300); }

/* THE DISCLAIMER IS LOUD. It is a legal notice on a page about tax, and a legal notice set in
   footer grey is a legal notice designed not to be read. Orange border, same treatment the
   draft banner gets, because both say "do not act on this as though it were finished". */
.wm-warn {
    border: 1px solid var(--btc-300);
    background: rgba(247, 147, 26, 0.06);
    padding: 18px 20px; display: grid; gap: 12px;
}
.wm-warn p { font-size: 14px; line-height: 1.65; color: var(--plat-100); }
.wm-warn strong { color: var(--btc-300); }

.wm-note { border: 1px solid var(--line-mid); padding: 20px; background: #0b0b0b; }
.wm-note p { font-size: 15px; line-height: 1.68; }
.wm-note .btn { margin-top: 16px; }
.wm-note-sub { font-size: 13px !important; color: var(--plat-500) !important; margin-top: 12px; }

.wm-block { border-left: 2px solid var(--line-mid); padding: 4px 0 4px 20px; display: grid; gap: 10px; }
.wm-block-h {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--btc-300);
}
.wm-block p { font-size: 15px; line-height: 1.68; }
.wm-block-note { color: var(--plat-500) !important; font-size: 13.5px !important; }

/* ---- the three mechanisms ---- */

/* THREE ACROSS, not three stacked. This grid never had a `grid-template-columns`, so it was a
   one-column grid: three tall cards in a row down the page. Side by side they are also easier
   to compare, which is the point of numbering them 01-03 in the first place. */
.wm-mechs {
    display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line-mid);
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
}
.wm-mech { background: var(--black); }

/* ---- a mechanism, closed ----
   The summary states the name AND the gate, so a reader who never opens one still cannot come
   away thinking the deduction is unconditional. That is the whole reason this was allowed to
   collapse at all. */
.wm-mech-sum {
    padding: 20px 22px; display: flex; gap: 16px; cursor: pointer;
    list-style: none; align-items: flex-start;
}
.wm-mech-sum::-webkit-details-marker { display: none; }
.wm-mech-sum:hover { background: #0b0b0b; }
.wm-mech-sum:focus-visible { outline: 2px solid var(--btc-300); outline-offset: -2px; }
.wm-mech-tt { display: grid; gap: 5px; min-width: 0; }
.wm-mech-tt h4 { margin: 0; }
.wm-mech-gate {
    font-size: 13px; line-height: 1.5; color: var(--plat-500);
}
/* The affordance: a plus that becomes a minus, drawn rather than typed so it cannot arrive as
   a font's idea of a plus sign. Same construction the FAQ already uses. */
.wm-mech-sum::after {
    content: ''; margin-left: auto; flex-shrink: 0;
    width: 11px; height: 11px; margin-top: 5px;
    background:
        linear-gradient(var(--btc-300), var(--btc-300)) center/11px 1.5px no-repeat,
        linear-gradient(var(--btc-300), var(--btc-300)) center/1.5px 11px no-repeat;
}
.wm-mech[open] .wm-mech-sum::after {
    background: linear-gradient(var(--btc-300), var(--btc-300)) center/11px 1.5px no-repeat;
}
.wm-mech[open] .wm-mech-sum { padding-bottom: 6px; }
.wm-mech-body { padding: 0 22px 22px 49px; }

@media (max-width: 620px) {
    /* The number column costs 33px of a 350px card and says nothing the order does not. */
    .wm-mech-body { padding-left: 22px; }
}
/* Numbered because they ARE a sequence: 179 is applied first, bonus to what is left, MACRS to
   the remainder. The order encodes the arithmetic rather than decorating a list. */
.wm-mech-n {
    font-family: var(--mono); font-size: 12px; letter-spacing: 0.1em;
    color: var(--btc-300); flex-shrink: 0; padding-top: 3px;
}
.wm-claim { font-size: 15.5px !important; line-height: 1.6 !important; color: var(--plat-100) !important; }

.wm-cond { margin-top: 16px; display: grid; gap: 0; }
/* STACKED, not two columns. A 190px label column inside a card that is now a third of the
   width leaves nothing for the value. The label sits above what it labels instead. */
.wm-cond > div {
    display: grid; gap: 3px;
    padding: 10px 0; border-top: 1px solid var(--line);
}
.wm-cond dt {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--plat-500); padding-top: 3px;
}
.wm-cond dd { margin: 0; font-size: 14px; line-height: 1.6; color: var(--plat-200); }
.wm-mech-note { font-size: 13.5px !important; color: var(--plat-500) !important; margin-top: 14px; }

.wm-gates { display: grid; gap: 1px; background: var(--line); border: 1px solid var(--line-mid);
            grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.wm-gate { background: var(--black); padding: 22px; display: grid; gap: 10px; align-content: start; }
.wm-gate p { font-size: 14.5px; line-height: 1.65; }
.wm-gate-note { color: var(--plat-500) !important; font-size: 13.5px !important; }

.wm-faq { margin-top: 20px; }

/* PLACED AFTER THE GRIDS IT OVERRIDES, and that is load-bearing. A media query adds no
   specificity, so `@media { .wm-mechs {...} }` and a plain `.wm-mechs {...}` are a tie that
   source order breaks. This block sat above the base rules and lost silently: the rail
   appeared, the mechanisms kept their 300px minimum, and three cards became two rows the
   moment the rail took 240px off the column. Nothing looked broken — the page was just
   taller. */
@media (min-width: 1180px) {
    .wm-layout {
        display: grid;
        grid-template-columns: minmax(0, 1fr) 240px;
        gap: 44px;
        align-items: start;
    }
    .wm-rail {
        position: sticky; top: 84px;
        margin-top: 8px; padding-top: 0; border-top: none;
        border-left: 1px solid var(--line-mid); padding-left: 22px;
    }
    /* The rail must not push the argument around. Both grids drop their minimum so three
       mechanisms still sit three across in the column the rail leaves behind. */
    .wm-mechs { grid-template-columns: repeat(auto-fit, minmax(255px, 1fr)); }
    .wm-vs { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
}

.wm-faq p { font-size: 14.5px; line-height: 1.68; color: var(--plat-200); padding-bottom: 18px; }

.wm-next { margin-top: 56px; padding-top: 28px; border-top: 1px solid var(--line-mid); }
.wm-next h2 { border: none; margin: 0 0 16px; padding: 0; font-size: 20px; }
.wm-next-links { display: flex; gap: 10px; flex-wrap: wrap; }

/* MOBILE SPACING, MEASURED. At 390px the gaps between blocks came to 654px on their own —
   seven per cent of the page in air, before a word of it was read. A section rule needs less
   room on a narrow screen than a wide one, because there is less across it. */
@media (max-width: 620px) {
    .wm-body > * + * { margin-top: 16px; }
    .wm-body h2 {
        font-size: 21px; margin-top: 34px; padding-top: 18px;
    }
    .wm-body h3 { margin-top: 26px; }
    .wm-tldr-cell, .wm-vs-col { padding: 18px 20px; }
    .wm-tldr-cell p { font-size: 14px !important; }
    .wm-warn, .wm-note { padding: 16px 18px; }
    .wm-gate { padding: 18px 20px; }
    .wm-next { margin-top: 36px; padding-top: 22px; }
    .wm-mech-sum { padding: 16px 18px; }
    .wm-mech-body { padding: 0 18px 18px; }
}

/* ---- what you are paying for ----
   Two purchases on two schedules, so the WHEN sits beside the amount rather than in a footnote.
   The total is present but deliberately quieter than its parts: it is the sum a customer wants
   for comparison, not a number anybody is ever invoiced. */
.itemised {
    margin-top: 20px; padding-top: 18px; border-top: 1px solid var(--line-mid);
}
.it-head {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--plat-500); margin-bottom: 14px;
}
.it-row {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 20px; padding: 11px 0; border-bottom: 1px solid var(--line);
}
.it-row:last-child { border-bottom: none; }
.it-what { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.it-lab { font-size: 14px; color: var(--plat-200); }
.it-sub { font-size: 11.5px; color: var(--plat-500); line-height: 1.5; }
.it-money { text-align: right; flex-shrink: 0; display: flex; flex-direction: column; gap: 3px; }
.it-val {
    font-size: 17px; color: var(--plat-100);
    font-variant-numeric: tabular-nums; letter-spacing: -0.01em;
}
/* WHEN it is due, next to how much. A schedule in a footnote is a schedule nobody read. */
.it-when { font-size: 11px; color: var(--plat-500); }

.it-row--total { border-top: 1px solid var(--line-mid); margin-top: 4px; padding-top: 14px; }
.it-row--total .it-lab { color: var(--plat-100); }
.it-row--total .it-val { color: var(--btc-300); }

@media (max-width: 560px) {
    .it-row { flex-direction: column; gap: 6px; }
    .it-money { text-align: left; }
}

/* ---- the discount strip under the site picker ----

   One bar the width of the row of sites, split into a segment per prepaid term. The segments are
   sized by the DISCOUNT, not shared equally, so the shape of the ladder reads before any number
   does: a sliver for 4%, half the bar for 20%. Three equal boxes would be a table wearing a
   bar's clothes.

   Only percentages live here. They are the one part of prepaid pricing that is identical at
   every site — the rates are not, and quoting one under a row of five sites would mean
   quoting a "from" price. The rates appear on the catalogue page once a site has been chosen. */
.pp-bar { margin-top: 28px; }
.pp-bar-lead {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--btc-300); margin-bottom: 10px;
}
.pp-bar-track {
    display: flex; align-items: stretch; gap: 2px;
    border: 1px solid var(--line-mid);
}
.pp-seg {
    /* min-width, because a 4% segment on a narrow screen would otherwise squeeze its own label
       out of existence. Below that the bar wraps rather than lying about the proportions. */
    min-width: 130px;
    padding: 14px 16px;
    background: var(--panel);
    display: flex; flex-direction: column; gap: 3px;
}
.pp-seg + .pp-seg { border-left: 1px solid var(--line); }
.pp-seg--best { background-image: var(--metal-btc-btn); }
.pp-seg-off {
    font-size: 17px; color: var(--plat-100); line-height: 1.15;
    font-variant-numeric: tabular-nums;
}
.pp-seg-yrs {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.06em;
    text-transform: uppercase; color: var(--plat-500);
}
/* On the accented segment the ground is bright metal, so the ink inverts rather than the label
   being left in a platinum that no longer has anything to contrast against. */
.pp-seg--best .pp-seg-off { color: var(--black); }
/* 0.70, not 0.62. Composited over the darkest stop of the gradient, 62% black on 10.5px text
   measures 3.97:1 — under the 4.5 floor, on the one segment the page is steering people to.
   0.68 is where it clears; 0.70 leaves a little room. Solved against BOTH ends of the gradient,
   because an average would pass while the dark end still failed. */
.pp-seg--best .pp-seg-yrs { color: rgba(0, 0, 0, 0.7); }
.pp-bar-foot {
    margin-top: 10px; font-size: 12px; color: var(--plat-500); line-height: 1.6;
}
@media (max-width: 720px) {
    .pp-bar-track { flex-wrap: wrap; }
    .pp-seg { flex: 1 1 100% !important; }
    .pp-seg + .pp-seg { border-left: none; border-top: 1px solid var(--line); }
}

/* ---- facility cards ----
   A whole card is the link, because "Texas" and "Start mining" are one decision and
   splitting them makes the reader aim at eleven characters of text. The arrow inside is
   an affordance, not a second target: it is a <span>, so there is exactly one link per
   card and a keyboard reaches it once. */
a.fac {
    display: flex;
    flex-direction: column;
    text-decoration: none;
    color: inherit;
}
.fac-place {
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--plat-500);
    margin-bottom: 10px;
}
.fac .h-card { margin-bottom: 6px; }
.fac-fuel {
    color: var(--btc-300) !important;
    font-size: 13px !important;
    margin-bottom: 12px;
}

.fac-spec {
    margin: 16px 0 0;
    padding-top: 14px;
    border-top: 1px solid var(--line);
    /* Pushed to the bottom so the specs line up across cards whose descriptions run to
       different lengths. Without it every card's figures sit at a different height and the
       grid reads as four unrelated things. */
    margin-top: auto;
}
.fac-row {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 4px 0;
    font-size: 12.5px;
}
.fac-row dt { color: var(--plat-500); }
.fac-row dd { margin: 0; color: var(--plat-200); text-align: right; font-variant-numeric: tabular-nums; }

.fac-go { margin-top: 16px; }
a.fac:hover .fac-go { color: var(--btc-200); }

/* An unfilled figure has to LOOK unfilled, and the way to do that is the MONO FACE, not a
   dimmer colour.

   The first version set it in --plat-600, which measures 3.02:1 on a card and fails as text
   outright. It also had the logic backwards: a placeholder is a flag, for the reader deciding
   whether to trust the page and for whoever has to come back and fill it in. Making it the
   quietest thing on the card hides it from both of them. So it is brighter than the label
   beside it — 8.6:1 against the note's 5.3 — and the mono face and brackets carry the
   "not filled in yet". */
.fac-ph,
.fac-row dd { font-family: var(--mono); font-size: 11.5px; }

.fac-note {
    margin-top: 26px;
    font-size: 12.5px;
    color: var(--plat-500);
    max-width: 74ch;
    line-height: 1.7;
}
.fac-ph { color: var(--plat-400); letter-spacing: 0.04em; }

/* ---- the chosen site, carried through the purchase ----
   Shown above the catalogue and again in the cart. Deliberately the same object in both
   places: the customer decided on three figures and has to still be looking at those three
   figures when they pay, or the choice was theatre. */
.fac-chosen {
    border: 1px solid var(--line-btc);
    background: var(--btc-wash);
    border-radius: var(--radius);
    padding: 18px 20px;
    margin-bottom: 30px;
}
/* A site that cannot take machines yet is not an error, but it must not wear the colour that
   means "good to go". */
.fac-chosen--wait { border-color: var(--line-mid); background: var(--panel); }

.fac-chosen-head {
    display: flex; align-items: flex-start; justify-content: space-between;
    gap: 16px; margin-bottom: 14px;
}
.fac-chosen-eyebrow {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--plat-500); margin-bottom: 5px;
}
.fac-chosen-name { font-size: 16px; color: var(--plat-100); }
.fac-chosen-region { color: var(--plat-400); font-size: 13px; }
.fac-change {
    font-family: var(--mono); font-size: 11px; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--btc-300); white-space: nowrap; flex-shrink: 0;
}
.fac-change:hover { color: var(--btc-200); }

.fac-chosen-spec {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 10px 22px; margin: 0; padding-top: 12px; border-top: 1px solid var(--line);
}
/* STACKED HERE, side by side on the cards, and the difference is the width.
   .fac-row is shared with the facility cards, where a column is about 200px and
   label-left/value-right reads as a spec line. In this banner each column is nearer
   300px, and space-between pushed "Site capacity" and "18 MW" so far apart that the
   eye stopped pairing them — four labels down one side of the page and four
   unrelated numbers down the other. */
.fac-chosen-spec .fac-row { display: block; padding: 0; }
.fac-chosen-spec dt {
    font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em;
    color: var(--plat-500);
}
/* The list rate, kept beside the one that replaced it. A price that silently changes when a
   button is pressed makes people re-read the page looking for the catch; showing what the
   commitment bought is the whole reason the number moved. */
.fac-was {
    display: block;
    margin-top: 3px;
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.04em;
    color: var(--plat-500);
    text-transform: none;
}

.fac-chosen-spec dd {
    margin: 3px 0 0; text-align: left; font-size: 13.5px; color: var(--plat-100);
    font-family: var(--sans); letter-spacing: 0;
}
.fac-lead { margin: 12px 0 0; font-size: 12.5px; color: var(--plat-400); }
/* The sentence that has to travel with any figure out of facilities.js. */
/* THE ONE THING ON THIS BLOCK A CUSTOMER MUST NOT MISS. Every site is at capacity, so this
   appears on the catalogue page and again in the cart — not once, at the end, after the card
   details are typed. It is set on the accent wash with an accent rule because it changes what
   the customer is buying: a place in a queue rather than a delivery date. */
.fac-full {
    margin: 14px 0 0;
    padding: 12px 14px;
    border-left: 3px solid var(--btc-300);
    background: rgba(247, 147, 26, 0.08);
    font-size: 13px;
    color: var(--plat-300);
    line-height: 1.6;
}
.fac-full strong { color: var(--btc-300); }

.fac-chosen-note { margin: 10px 0 0; font-size: 11.5px; color: var(--plat-500); line-height: 1.6; }

@media (max-width: 640px) {
    .fac-chosen-head { flex-direction: column; gap: 8px; }
}

.card h3 { margin-bottom: 12px; }
.card p { color: var(--plat-400); font-size: 14.5px; line-height: 1.66; }

/* ===== Two-track split ===== */

.tracks {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
}
.tracks::before {
    content: '';
    position: absolute;
    top: -1px; left: 0; right: 0;
    height: 1px;
    background-image: var(--edge-plat);
    z-index: 2;
}

.track {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: 44px 38px 38px;
    background: var(--panel);
    text-decoration: none;
    overflow: hidden;
    transition: background 0.28s;
}
/* Metal edge that lights up along the top on hover. */
.track::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 2px;
    background-image: var(--metal-btc-flat);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.45s cubic-bezier(0.3, 0, 0.2, 1);
    z-index: 3;
}
.track:hover { background: var(--panel-hover); }
.track:hover::before { transform: scaleX(1); }

.track-tag {
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--btc-300);
    margin-bottom: 20px;
}
.track h3 {
    font-size: clamp(22px, 2.5vw, 30px);
    margin-bottom: 16px;
    letter-spacing: -0.032em;
    color: var(--plat-100);
}
.track p { color: var(--plat-400); font-size: 15px; line-height: 1.66; }
.track ul { list-style: none; margin: 28px 0 32px; display: grid; gap: 0; }
.track li {
    position: relative;
    padding: 11px 0 11px 24px;
    font-size: 14px;
    color: var(--plat-400);
    border-top: 1px solid var(--line);
}
.track li:last-child { border-bottom: 1px solid var(--line); }
.track li::before {
    content: '';
    position: absolute;
    left: 2px;
    top: 18px;
    width: 6px;
    height: 6px;
    background-image: var(--metal-plat-flat);
}
.track .arrow-link { margin-top: auto; }

/* ===== Numbered process ===== */

.steps { counter-reset: step; }
.step {
    position: relative;
    display: grid;
    grid-template-columns: 92px 1fr;
    gap: 32px;
    padding: 36px 0;
    align-items: start;
}
.step::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 1px;
    background-image: var(--edge-plat-short);
}
.step:last-child::after {
    content: '';
    position: absolute;
    bottom: 0; left: 0; right: 0;
    height: 1px;
    background-image: var(--edge-plat-short);
}
.step-num {
    counter-increment: step;
    font-family: var(--mono);
    font-size: 13px;
    font-weight: 500;
    letter-spacing: 0.16em;
    padding-top: 5px;
    background-image: var(--metal-plat);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--plat-200);
}
.step-num::before { content: '0' counter(step); }
.step h3 { font-size: 19px; margin-bottom: 11px; color: var(--plat-100); }
.step p { color: var(--plat-400); font-size: 15px; max-width: 76ch; line-height: 1.7; }

/* ===== Spec table — lit plate ===== */

.spec {
    position: relative;
    border: 1px solid var(--line);
    background-image: linear-gradient(168deg, rgba(229,228,226,0.045), transparent 46%);
}
.spec::before {
    content: '';
    position: absolute;
    top: -1px; left: -1px; right: -1px;
    height: 1px;
    background-image: var(--edge-plat);
}
.spec-row {
    display: grid;
    grid-template-columns: 260px 1fr;
    gap: 28px;
    padding: 22px 30px;
    border-top: 1px solid var(--line);
    align-items: baseline;
}
.spec-row:first-child { border-top: none; }
.spec-key {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--plat-300);
}
.spec-val { font-size: 15px; color: var(--plat-200); line-height: 1.6; }
.spec-val small { display: block; margin-top: 7px; color: var(--text-dim); font-size: 13px; line-height: 1.6; }

/* ===== Checklist ===== */

.checks { list-style: none; }
.checks li {
    position: relative;
    padding: 16px 0 16px 32px;
    font-size: 14.5px;
    color: var(--plat-400);
    line-height: 1.66;
    border-top: 1px solid var(--line);
}
.checks li:last-child { border-bottom: 1px solid var(--line); }
.checks li::before {
    content: '';
    position: absolute;
    left: 0;
    top: 24px;
    width: 14px;
    height: 8px;
    border-left: 1.5px solid var(--plat-200);
    border-bottom: 1.5px solid var(--plat-200);
    transform: rotate(-45deg);
}
.checks strong { color: var(--plat-000); font-weight: 600; }

/* ===== FAQ ===== */

.faq { border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
    list-style: none;
    cursor: pointer;
    padding: 26px 48px 26px 0;
    font-size: 16px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--plat-200);
    position: relative;
    transition: opacity 0.2s;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { opacity: 0.78; }
.faq summary::before,
.faq summary::after {
    content: '';
    position: absolute;
    right: 4px;
    top: 50%;
    background-image: var(--metal-btc-flat);
    /* The summary itself is clipped to text; its pseudos must not be. */
    -webkit-background-clip: border-box;
    background-clip: border-box;
    transition: transform 0.3s cubic-bezier(0.3, 0, 0.2, 1), opacity 0.3s;
}
.faq summary::before { width: 13px; height: 1.5px; margin-top: -0.75px; }
.faq summary::after  { width: 1.5px; height: 13px; margin-top: -6.5px; right: 9.75px; }
.faq details[open] summary::after { transform: scaleY(0); opacity: 0; }
.faq details p {
    color: var(--plat-400);
    font-size: 15px;
    padding: 0 48px 28px 0;
    max-width: 84ch;
    line-height: 1.72;
}

/* ===== CTA band ===== */

.cta-band {
    position: relative;
    border: 1px solid var(--line-mid);
    background-color: var(--panel);
    background-image: linear-gradient(168deg, rgba(229,228,226,0.05), transparent 50%);
    padding: 76px 44px;
    text-align: center;
    overflow: hidden;
}
.cta-band::before {
    content: '';
    position: absolute;
    inset: 0 0 auto 0;
    height: 2px;
    background-image: var(--metal-btc-flat);
    z-index: 2;
}
.cta-band::after {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse 620px 260px at 50% 0%, rgba(247,147,26,0.10), transparent 70%);
    pointer-events: none;
}
.cta-band > * { position: relative; z-index: 1; }

/* ===== Forms ===== */

.form {
    position: relative;
    display: grid;
    gap: 20px;
    border: 1px solid var(--line);
    background: var(--panel);
    padding: 34px;
}
.form::before {
    content: '';
    position: absolute;
    top: -1px; left: -1px; right: -1px;
    height: 1px;
    background-image: var(--edge-plat);
}
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.field { display: grid; gap: 9px; }
.field label {
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.17em;
    text-transform: uppercase;
    color: var(--plat-300);
}
.field input,
.field select,
.field textarea {
    font-family: var(--sans);
    font-size: 14.5px;
    color: var(--plat-100);
    background: var(--panel-solid);
    border: 1px solid var(--line-mid);
    padding: 12px 14px;
    width: 100%;
    transition: border-color 0.18s, box-shadow 0.18s;
}
.field textarea { resize: vertical; min-height: 128px; line-height: 1.6; }
.field input:focus,
.field select:focus,
.field textarea:focus {
    outline: none;
    border-color: var(--btc-300);
    box-shadow: inset 0 0 0 1px rgba(247,147,26,0.35);
}
.field input::placeholder, .field textarea::placeholder { color: var(--text-dim); }
.field select { appearance: none; cursor: pointer; }
.form-note { font-size: 12.5px; color: var(--text-dim); line-height: 1.6; }

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

.footer { position: relative; padding: 76px 0 44px; }
.footer::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 1px;
    background-image: var(--edge-plat);
}
.footer-top {
    display: grid;
    grid-template-columns: 1.7fr 1fr 1fr 1fr;
    gap: 44px;
    padding-bottom: 52px;
    border-bottom: 1px solid var(--line);
}
.footer-blurb { color: var(--plat-400); font-size: 13.5px; margin-top: 20px; max-width: 34ch; line-height: 1.66; }
.footer-col h4 {
    font-family: var(--mono);
    font-size: 10.5px;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--plat-500);
    margin-bottom: 20px;
    font-weight: 500;
}
.footer-col a {
    display: block;
    color: var(--plat-400);
    text-decoration: none;
    font-size: 14px;
    padding: 6px 0;
    transition: color 0.18s;
}
.footer-col a:hover { color: var(--btc-300); }
.footer-bottom {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 20px;
    padding-top: 30px;
    font-family: var(--mono);
    font-size: 11.5px;
    letter-spacing: 0.04em;
    color: var(--text-dim);
    flex-wrap: wrap;
}

/* ===== "Inside a site" diagram =====
   Interactive cutaway. Geometry is recomputed per frame by site-diagram.js from
   projected model coordinates — it measures nothing, so leader lines stay welded
   to their anchors and drag/zoom need no geometry queries. The static frame ships
   in the HTML, so the diagram is complete and correct with JS disabled. */

.dg-wrap {
    position: relative;
    border: 1px solid var(--line);
    /* No border along the bottom: the flame burns its source line there, and
       overflow:hidden clips the canvas at the padding box, so a border below it
       can never be covered — it would always read as a second, grey rule under
       the orange one. The flame IS the bottom perimeter, the same way it is at
       the foot of the hero zone. */
    border-bottom: none;
    background: var(--panel);
    overflow: hidden;
}

/* The drawing breaks out of the text measure to its own. The child combinator
   is doing real work: on the home page the outermost element is the .dg-wrap
   itself, on the hosting page it is the .dg-views grid holding two of them, and
   only the outer one may break out — applying this to both would offset the
   inner wraps a second time.

   Centred with a MARGIN, not a transform. These same elements carry .reveal,
   which owns transform to animate them in — and .reveal.in resets it to none at
   equal specificity and later in the file. A translate here therefore holds
   until the element scrolls into view and then vanishes, dropping the box half
   a wrap to the right exactly when someone first looks at it.

   The margin resolves against the parent's content width and the width against
   the viewport, so the two together land the centre of the box on the centre of
   the page without anything being measured. The gutters are wider than any
   scrollbar, so subtracting them from 100vw cannot overflow the line. */
/* The third selector is the fuel switch's doing. energy.html wraps each pair in
   a .dg-fuel-pane, which put .dg-views one level deeper and silently stopped
   this rule matching — the child combinator above is deliberate, so it did not
   fall through. The drawings kept rendering, just at the 1144px text measure
   instead of the 1520px diagram measure, a quarter narrower than the identical
   drawings one click away on index.html and hosting.html. Nothing looked broken;
   it only showed against the other pages.

   The PANE must not take the width itself. It also holds .dg-scale and the two
   .dg-list columns, and those belong on the text measure. And the centring still
   resolves through the pane without measuring anything, because the pane is a
   plain block: its content width is .wrap's content width, so the 50% here means
   what it always meant. */
.wrap > .dg-wrap,
.wrap > .dg-views,
.wrap > .dg-fuel-pane > .dg-views {
    --dg-w: min(var(--max-dg), 100vw - var(--gut) * 2);
    width: var(--dg-w);
    margin-left: calc(50% - var(--dg-w) / 2);
}
.dg-wrap::before {
    content: '';
    position: absolute;
    top: -1px; left: -1px; right: -1px;
    height: 1px;
    background-image: var(--edge-plat);
    z-index: 4;
}

.site-diagram { display: block; width: 100%; height: auto; cursor: grab; touch-action: pan-y; }
.dg-wrap.is-dragging .site-diagram { cursor: grabbing; }
.site-diagram:focus-visible { outline: 1px solid var(--btc-300); outline-offset: -2px; }

/* Surfaces, lit from above: roof brightest, long sides mid, ends darkest. The
   interior is darker than anything outside it so the machines read against it. */
/* One weight for every drawing. These were split in two — cutaway weights for
   the mine and the container, heavier ones for the wellpad — and the three
   drawings ended up looking like three different materials. This is the shared
   middle: a lit face clears 3:1 against the ground everywhere, and the cutaways
   still read through to the machines behind them, which is what the low weights
   were protecting in the first place. */
/* Not a layer of the drawing — DATA carried in a path, and never rendered.

   diagram-engine.js unions the solid layers into it every frame, and
   hero-anim.js reads its d to subtract the plant's silhouette from the gas
   field on the canvas behind. display:none costs nothing to paint and is what
   keeps it out of the picture; the attribute is still readable.

   THE RULE FOR WHAT GOES IN IT, because the set is easy to get wrong later: a
   layer contributes iff it declares a FILL. Filled area is surface you look AT;
   the stroke-only layers are marks on surfaces that already contribute, and
   .dg-back's guy wires are hairlines in open air with no silhouette at all.

   The ground counts. It was left out at first on the theory that a 0.04 surface
   spanning most of the frame should not blank the field — which was measured
   against a prototype that PAINTED the silhouette, where it was true. Erasing
   leaves the ground exactly as translucent as it was. Leaving it out is also
   what made the landfill and flare drawings, the only two with a ground plane,
   still show gas through them while every other drawing looked clean.

   The list lives in diagram-engine.js's OCCLUDING, with the full argument. */
.dg-occluder { display: none; }

.dg-top    { fill: rgba(229, 228, 226, 0.42); stroke: none; }
.dg-side   { fill: rgba(229, 228, 226, 0.30); stroke: none; }
.dg-end    { fill: rgba(229, 228, 226, 0.20); stroke: none; }
.dg-inside { fill: rgba(0, 0, 0, 0.62);        stroke: none; }

/* Hairlines that belong BEHIND the machines: far-wall corrugation, floor
   grating, rack uprights. Painting these after the ASICs stripes them across
   the machines, which is why the back layer exists at all. */
/* Ground: the graded surface under everything. Deliberately the faintest thing
   in the drawing — it is what the plant stands ON, and at .dg-back weight it
   competed with the plant itself. */
.dg-ground {
    /* A faint fill, because this layer now carries the graded surface itself
       and not only the grid on it. The grid lines share the layer and are
       open subpaths, which enclose no area and so take no fill. */
    fill: rgba(229, 228, 226, 0.04);
    stroke: var(--line);
    stroke-width: 0.5;
}

.dg-back   { fill: none; stroke: rgba(229, 228, 226, 0.42); stroke-width: 0.7; }

.dg-asics  { fill: rgba(229, 228, 226, 0.10);
             stroke: var(--line-mid); stroke-width: 0.6; }

/* Everything in front: fans, louvres, seams, hinges, panels, dishes. */
.dg-detail {
    fill: none;
    /* Raised with the fills: at --line-hi (0.42) a detail stroke sat at the
       same weight as the lit face it is drawn on and disappeared. */
    stroke: rgba(229, 228, 226, 0.72);
    stroke-width: 0.8;
    stroke-linecap: round;
}

/* The one orange element: gas in, power along the run, into the container. */
.dg-flow {
    fill: none;
    stroke: var(--btc-300);
    stroke-width: 2;
    stroke-dasharray: 6 11;
    opacity: 0.9;
    animation: dg-flow 2.6s linear infinite;
}
@keyframes dg-flow { to { stroke-dashoffset: -17; } }

/* The flare flame, on the energy page. This is the one filled, coloured object
   in the entire drawing family, and it is a deliberate exception to "orange is
   a stroke, never a surface": a flare flame IS a surface, it is the subject of
   that page, and outlining it would read as a diagram of a flame rather than a
   flame. It stays honest to the rest of the family by being translucent, the
   same way every platinum face is.

   Three nested tongues arrive as one path. Under fill-rule nonzero the overlaps
   do not cancel, so the fill is a single silhouette and the stroke is what
   draws the structure inside it.

   The flicker is a scale about the base — how a flare actually moves — rather
   than a change of opacity, which reads as a lamp. The engine rewrites this
   path's d on every frame of rotation; a CSS transform composes with that
   rather than fighting it. Reduced motion is already covered by the blanket
   rule on .site-diagram * further down. */
.dg-flame {
    fill: rgba(247, 147, 26, 0.30);
    stroke: var(--btc-300);
    stroke-width: 1.1;
    stroke-linejoin: round;
    transform-box: fill-box;
    transform-origin: 50% 100%;
    animation: dg-flare 1.9s ease-in-out infinite alternate;
}
@keyframes dg-flare {
    from { transform: scaleY(0.94) scaleX(1.03); }
    to   { transform: scaleY(1.07) scaleX(0.97); }
}

/* Hover highlight, painted over the hovered region only. */
.dg-highlight {
    fill: rgba(247, 147, 26, 0.16);
    stroke: var(--btc-300);
    stroke-width: 1.1;
    stroke-linejoin: round;
    pointer-events: none;
    transition: opacity 0.16s;
}

/* Invisible pointer targets. Emitted largest-first so the smallest region ends
   up topmost and wins. */
.dg-hit { fill: transparent; stroke: none; pointer-events: all; cursor: pointer; }

/* Leaders are scaffolding: they tell you which bubble belongs to which part,
   and the drawing should carry the eye, not the lines to the labels. Dropped
   from --line-mid at width 1 to --line at 0.9 — a little under half the ink.
   The hot state is deliberately untouched, so hovering still snaps one leader
   to full orange against much quieter neighbours than before. */
.dg-lead { stroke: var(--line); stroke-width: 0.9; transition: stroke 0.16s, stroke-width 0.16s; }
.dg-lead.is-hot { stroke: var(--btc-300); stroke-width: 1.4; }
.dg-node { fill: var(--btc-300); }

/* Callout bubbles are HTML so the text wraps for real. */
.dg-callout {
    position: absolute;
    z-index: 3;
    width: 17.2%;
    transform: translateY(-50%);
    padding: 11px 13px;
    background: rgba(0, 0, 0, 0.66);
    border: 1px solid var(--line-mid);
    backdrop-filter: blur(3px);
    -webkit-backdrop-filter: blur(3px);
    cursor: pointer;
    transition: border-color 0.16s, background 0.16s;
}
.dg-callout--l { right: 80.47%; text-align: right; }
.dg-callout--r { left: 80.47%; }
.dg-callout.is-hot,
.dg-callout:focus-visible {
    border-color: var(--btc-300);
    background: rgba(30, 16, 2, 0.86);
    outline: none;
}
/* Everything dims a little while one part is called out. */
.dg-wrap.is-focused .dg-callout:not(.is-hot) { opacity: 0.45; }

.dg-c-title {
    display: block;
    font-family: var(--mono);
    font-size: clamp(9px, 0.83vw, 11px);
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--plat-200);
    margin-bottom: 5px;
}
.dg-callout.is-hot .dg-c-title { color: var(--btc-200); }
.dg-c-desc {
    display: block;
    font-size: clamp(10.5px, 0.94vw, 12.5px);
    line-height: 1.42;
    color: var(--plat-500);
}

/* Controls */
/* A view can name what it is. Sits along the top, clear of the left bubble
   column (which ends at 19.53%), the hint at bottom-left and the controls at
   bottom-right. */
.dg-note {
    position: absolute;
    left: 21%;
    top: 14px;
    z-index: 3;
    max-width: 58%;
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.16em;
    line-height: 1.7;
    text-transform: uppercase;
    color: var(--plat-400);
    pointer-events: none;
}

/* The route on. The home page shows the whole site; the next step down — one
   container — lives on the hosting page, so the second segment is a link. It
   reads as the same kind of control as the hosting page's slider, because it
   does the same job. */
.dg-toggle {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--line-mid);
    margin-bottom: 22px;
}
.dg-toggle > * {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    padding: 10px 16px;
    font-family: var(--mono);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
}
.dg-toggle-on { color: #000000; background-image: var(--metal-btc-btn); }
/* A divider between every pair, since the control carries all three stops now
   and the current one can sit at either end or in the middle. It used to hang
   off .dg-toggle-to, which only worked while there was exactly one link. */
.dg-toggle > * + * { border-left: 1px solid var(--line-mid); }

.dg-toggle-to {
    color: var(--plat-400);
    transition: color 0.2s, background-color 0.2s;
}
.dg-toggle-to:hover,
.dg-toggle-to:focus-visible {
    color: var(--btc-300);
    background-color: var(--panel-hover);
    outline: none;
}
.dg-toggle-to svg { transition: transform 0.24s cubic-bezier(0.3, 0, 0.2, 1); }
.dg-toggle-to:hover svg { transform: translateX(3px); }

/* A link back up the chain leads with its arrow, so its travel goes the other
   way. Doubled class rather than relying on source order: an equal-specificity
   override that only wins because of where it sits in the file is the kind of
   thing that breaks silently when rules move. */
.dg-toggle-to.dg-toggle-to--back:hover svg { transform: translateX(-3px); }

/* Three segments instead of two, so they need to give up more to fit a narrow
   screen. The longest label is thirteen characters; at this size three of them
   plus their padding come to about 280px, inside the 320px a 360px phone
   leaves after gutters. */
@media (max-width: 460px) {
    .dg-toggle { display: flex; }
    .dg-toggle > * {
        flex: 1;
        justify-content: center;
        padding: 10px 5px;
        font-size: 9.5px;
        letter-spacing: 0.06em;
    }
    .dg-toggle svg { width: 12px; height: 12px; }
}

.dg-controls {
    position: absolute;
    right: 14px;
    bottom: 14px;
    z-index: 3;
    display: flex;
    gap: 6px;
}
.dg-controls button {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--plat-300);
    background: rgba(0, 0, 0, 0.6);
    border: 1px solid var(--line-mid);
    padding: 6px 10px;
    min-width: 30px;
    cursor: pointer;
    transition: color 0.16s, border-color 0.16s;
}
.dg-controls button:hover,
.dg-controls button:focus-visible {
    color: var(--btc-300);
    border-color: var(--btc-300);
    outline: none;
}

.dg-hint {
    position: absolute;
    left: 14px;
    bottom: 16px;
    z-index: 3;
    font-family: var(--mono);
    font-size: 10px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--plat-600);
    pointer-events: none;
}

/* The same callouts as a stacked list, for widths where the drawing is too
   dense to read and there is no pointer to hover with. Generated from the same
   array, so they cannot drift. */
.dg-list { display: none; list-style: none; counter-reset: dg; margin-top: 4px; }
.dg-list li {
    position: relative;
    counter-increment: dg;
    padding: 18px 0 18px 44px;
    border-top: 1px solid var(--line);
}
.dg-list li:last-child { border-bottom: 1px solid var(--line); }
.dg-list li::before {
    content: '0' counter(dg);
    position: absolute;
    left: 0;
    top: 20px;
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.14em;
    color: var(--btc-300);
}
.dg-list-title {
    display: block;
    font-size: 15px;
    font-weight: 600;
    letter-spacing: -0.02em;
    color: var(--plat-100);
    margin-bottom: 4px;
}
.dg-list-desc { display: block; font-size: 14.5px; color: var(--plat-400); line-height: 1.6; }

/* ===== Detail slider — the whole container, or one machine =====

   Two diagrams share one grid cell, so the taller sets the height and the
   section never resizes as the slider moves. --d (0..1) is written on the
   wrapper by site.js and drives the cross-dissolve; the small scale difference
   either side of it is what makes the change read as diving in rather than as
   two pictures swapping.

   Every id in the second view is prefixed a- by the generator. Two diagrams on
   one page would otherwise both answer to dg-flow, dg-s0-top and dg-zoom-in. */

/* The slider had a 1px hairline for a track, which is easy to miss entirely if
   you have never seen the page before — it read as a rule between two labels
   rather than as something you could take hold of. Three changes: a track thick
   enough to be a track, a thumb with a grip on it, and a hint that says what to
   do and then gets out of the way once you have done it. */
/* --- The fuel switch ---
   Which PAIR of drawings is on screen. The slider then picks between the two
   drawings inside that pair, so these are two different axes and have to look
   like two different controls — they sit directly above one another.

   That is why the selected state here is a rule under the word rather than the
   metal fill the chain toggle and the calculator use: two filled segments
   stacked would read as one control that had somehow been pressed twice. */
/* BLOCK-LEVEL flex, not inline-flex, with max-content to keep the shrink-to-fit
   width. .dg-toggle immediately above is inline-flex, so an inline-flex switch
   sits on the SAME LINE as it and the two controls read as one five-segment
   thing — which is precisely the confusion the separate treatment below exists
   to prevent. */
.dg-fuel {
    display: flex;
    width: max-content;
    max-width: 100%;
    align-items: stretch;
    border: 1px solid var(--line-mid);
    margin-bottom: 4px;
}
.dg-fuel button {
    position: relative;
    padding: 10px 16px 12px;
    font-family: var(--mono);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    white-space: nowrap;
    color: var(--plat-400);
    background: transparent;
    border: none;
    cursor: pointer;
    transition: color 0.18s, background 0.18s;
}
.dg-fuel button + button { border-left: 1px solid var(--line-mid); }
.dg-fuel button:hover { color: var(--plat-100); background: var(--panel-hover); }
.dg-fuel button[aria-pressed="true"] { color: var(--btc-300); }
/* Inset from the edges so it underlines the word rather than bordering the
   button, which would just look like a thicker box. */
.dg-fuel button[aria-pressed="true"]::after {
    content: "";
    position: absolute;
    left: 14px;
    right: 14px;
    bottom: 5px;
    height: 2px;
    background: var(--btc-300);
}
.dg-fuel button:focus-visible { outline: 2px solid var(--btc-300); outline-offset: -3px; }

/* Hiding a pane is already guaranteed by the global `[hidden] { display: none
   !important; }` near the top of this file, which no ordinary rule here can
   beat — so this is a restatement for whoever reads the fuel switch in one
   place, not the thing doing the work.

   It is also why the no-JS override that build-diagram.js emits has to carry
   !important of its own: to show a hidden pane again it must outrank that
   global rule, and specificity is the only lever left once both are important. */
.dg-fuel-pane[hidden] { display: none; }

@media (max-width: 460px) {
    .dg-fuel { width: auto; }
    .dg-fuel button {
        flex: 1;
        padding: 10px 5px 12px;
        font-size: 9.5px;
        letter-spacing: 0.06em;
    }
    .dg-fuel button[aria-pressed="true"]::after { left: 8px; right: 8px; }
}

.dg-scale {
    display: flex;
    align-items: center;
    gap: 18px;
    margin-top: 18px;      /* room for the hint, which sits above the track */
    margin-bottom: 20px;
}
.dg-scale-track {
    flex: 1;
    min-width: 0;
    position: relative;
    display: flex;
    align-items: center;
}

/* Shown until the first drag, then faded. Arrows drift apart so the control
   reads as something with travel in it rather than a static marker. */
.dg-scale-hint {
    position: absolute;
    left: 50%;
    bottom: 100%;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 3px;
    font-family: var(--mono);
    font-size: 9.5px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--btc-300);
    white-space: nowrap;
    pointer-events: none;
    transition: opacity 0.45s;
}
.dg-scale-hint svg { width: 12px; height: 12px; }
.dg-scale-hint svg:first-child { animation: dg-nudge-l 1.9s ease-in-out infinite; }
.dg-scale-hint svg:last-child  { animation: dg-nudge-r 1.9s ease-in-out infinite; }
@keyframes dg-nudge-l { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-3px); } }
@keyframes dg-nudge-r { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(3px); } }
.dg-scale.is-used .dg-scale-hint { opacity: 0; }
@media (prefers-reduced-motion: reduce) {
    .dg-scale-hint svg { animation: none; }
}
.dg-scale-end {
    font-family: var(--mono);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--plat-400);
    white-space: nowrap;
    transition: color 0.2s;
}
.dg-scale-end.is-on { color: var(--btc-300); }

.dg-scale-input {
    flex: 1;
    min-width: 0;
    -webkit-appearance: none;
    appearance: none;
    height: 26px;
    background: transparent;
    cursor: ew-resize;   /* the pointer says it slides */
}
.dg-scale-input::-webkit-slider-runnable-track { height: 4px; background: var(--line-hi); }
.dg-scale-input::-moz-range-track           { height: 4px; background: var(--line-hi); }
/* Square, like everything else on this site. */
.dg-scale-input::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 13px;
    height: 26px;
    margin-top: -11px;
    border: none;
    border-radius: 0;
    background-image:
        /* Two dark grip lines over the metal, so the thumb reads as a handle
           rather than as a coloured tick on the track. */
        linear-gradient(to right, transparent 4px, rgba(0,0,0,0.42) 4px 5px,
                                  transparent 5px 8px, rgba(0,0,0,0.42) 8px 9px,
                                  transparent 9px),
        var(--metal-btc-btn);
}
.dg-scale-input::-moz-range-thumb {
    width: 13px;
    height: 26px;
    border: none;
    border-radius: 0;
    background-image: var(--metal-btc-btn);
}
.dg-scale-input:focus-visible { outline: 1px solid var(--btc-300); outline-offset: 4px; }

.dg-views { display: grid; }
.dg-views > .dg-wrap { grid-area: 1 / 1; pointer-events: none; }
.dg-views > .dg-wrap.is-on { pointer-events: auto; }
/* The crossfade is by position, not by view name. It used to be keyed to
   --cont and --asic, which meant a third pair of views anywhere on the site
   would render both halves at full opacity on top of each other. The callouts
   and controls of each view live inside its own wrapper, so the two wrappers
   really are the first and last children here. */
.dg-views > .dg-wrap:first-child { opacity: calc(1 - var(--d, 0)); }
.dg-views > .dg-wrap:last-child  { opacity: var(--d, 0); }

/* The slight push-in as the hosting slider travels is deliberately NOT
   generalised. It belongs to a slider that changes subject — a container, then
   one machine inside it — where a little dolly sells the change of scale. The
   energy page's slider changes the same pad from one state to another, and any
   movement there would break the illusion that you are looking at one site.
   Kept small even here: the callout bubbles are positioned against the unscaled
   wrapper, so a large difference would visibly unhook the leaders mid-drag. */
.dg-wrap--cont .site-diagram { transform: scale(calc(1 + var(--d, 0) * 0.06)); }
.dg-wrap--asic .site-diagram { transform: scale(calc(0.95 + var(--d, 0) * 0.05)); }

@media (prefers-reduced-motion: reduce) {
    .dg-wrap--cont .site-diagram, .dg-wrap--asic .site-diagram { transform: none; }
}

@media (max-width: 900px) {
    /* ---- the drawings on a phone ----
     *
     * These used to be display:none below 900px, with the ordered list underneath standing in
     * for them. That was a defensible call and the wrong one: the drawings are the most
     * distinctive thing on the site, and a visitor on a phone — which is most of them — was
     * getting a bullet list where everybody else got a cutaway.
     *
     * WHY THEY COULD NOT SIMPLY BE UNHIDDEN. The viewBox is 1280x470. Fitted to a 390px screen
     * that renders at 348x128, a scale of 0.272: a letterbox strip four times smaller than the
     * drawing was designed to be read at, with eight 16px callout bubbles pinned over it. Every
     * one of those numbers is measured, and together they are why hiding it looked reasonable.
     *
     * So the drawing gets its own horizontal scroller at a width where it is legible — 820px,
     * a scale of 0.641, which is 2.4x what fitting to the screen gives — and you swipe it. That
     * is the convention the rest of this site already uses for content wider than the screen,
     * and it keeps the page itself from ever scrolling sideways.
     *
     * THE CALLOUT BUBBLES COME OFF, and the list stays. Eight bubbles over a drawing that is
     * now partly off-screen would be unreadable and would land on nothing. The <ol> below says
     * the same eight things, in the same order, at a size somebody can actually read. The
     * drawing is the picture; the list is the labels. */
    .dg-wrap {
        display: block;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        /* Panning belongs to the browser. Without this the engine's pointermove handler and
           the scroller fight over every horizontal swipe, and the drawing rotates when you
           meant to scroll it. Drag-to-rotate is a mouse affordance and it stays one. */
        touch-action: pan-x pan-y;
    }
    /* SHIFTED LEFT BY THE WIDTH OF THE CALLOUT GUTTER.
     *
     * Measuring said the drawing was legible. Looking at a screenshot said it was not the
     * thing on screen: the left third of the viewBox is empty space that exists to hold the
     * callout bubbles, and with those hidden the reader's first view was a blank field with
     * the mine off the right edge. A scroller that opens on nothing is a scroller nobody
     * swipes.
     *
     * A negative margin rather than a scroll position, because setting scrollLeft would mean
     * reading layout at runtime, which this project does not do. The drawing starts where the
     * drawing starts, and the gutter is still reachable by swiping back if anybody wants it. */
    .dg-wrap .site-diagram {
        width: 820px; max-width: none; height: auto;
        margin-left: -250px;
    }
    .dg-callout { display: none; }

    /* THE HINT DESCRIBED A MOUSE. "Drag to rotate, hover a part to identify it, scroll to
       zoom" is three things a phone cannot do: dragging now scrolls, there is no hover, and
       there is no wheel. It also overlapped the zoom buttons at this width. The buttons stay
       — they work by tapping — and the sentence goes. */
    .dg-hint { display: none; }

    .dg-list { display: block; }
    /* Two lists, and the slider still picks which one you are reading. Keyed to
       which END the slider is at rather than to the view names, so a second
       pair of views elsewhere on the site does not silently show both lists at
       once. site.js writes data-at alongside data-view for exactly this. */
    .dg-views[data-at="lo"] ~ .dg-list:last-of-type,
    .dg-views[data-at="hi"] ~ .dg-list:first-of-type { display: none; }
}

/* The global reduced-motion rule only forces animation-duration to 0.01ms, which
   strobes an infinite animation rather than stopping it. Killing the NAME halts
   it. site-diagram.js separately declines to start the idle sweep — but keeps
   drag, zoom and hover working, since those are user-initiated. */
@media (prefers-reduced-motion: reduce) {
    .site-diagram *, .dg-flow { animation: none; }
}

/* ===== Reveal on scroll ===== */

.reveal {
    opacity: 0;
    transform: translateY(14px);
    transition: opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1), transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) { .reveal { opacity: 1; transform: none; } }

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

@media (max-width: 980px) {
    .grid-4 { grid-template-columns: repeat(2, 1fr); }
    .grid-3 { grid-template-columns: 1fr; }
    .stats { grid-template-columns: repeat(2, 1fr); }
    .tracks { grid-template-columns: 1fr; }
    .spec-row { grid-template-columns: 1fr; gap: 8px; }
    .footer-top { grid-template-columns: 1fr 1fr; }
}

/* ===== Nav width =====

   THESE NUMBERS ARE MEASURED, AND THEY HAD STOPPED BEING TRUE.

   The comment here used to say "five items plus a CTA", and the breakpoints were set for that
   nav. The nav is now eight links plus the order badge, the portal button and the CTA, and
   nobody moved the breakpoints as it grew — so the full-size row needed about 1480px in a
   viewport that was only asked to be 1241px wide.

   The result was that the marketing site scrolled sideways at 1280 and 1366, which are the two
   commonest desktop widths there are, and again from 941 to 1200. It was 7px at its mildest on
   the plainest page, which is why it survived: small enough to look like a rounding artifact,
   present on every page.

   Measured with the longest CTA on the page, which is the worst case:
     full-size row   needs ~1480px  ->  only used above 1560
     compact row     needs ~1200px  ->  used from 1241 to 1560
     drawer          always fits    ->  used at 1240 and below

   TO RE-DERIVE AFTER ADDING A NAV ITEM: load the page with the longest CTA, step the viewport
   down, and watch document.body.scrollWidth against clientWidth. The first width where they
   diverge is the floor for that tier. Do not guess at this — guessing is what produced a
   breakpoint 300px too low that shipped for months. */
@media (max-width: 1560px) {
    .nav-inner { gap: 18px; }
    .nav-links a { padding: 9px 10px; font-size: 13px; }
    .nav-cta { margin-left: 8px; }
    .nav-links a.nav-cta { padding: 10px 14px; }
}

/* The drawer, at 1240 rather than 940: the compact row above needs ~1200px and was being asked
   to render at 941. Between 941 and 1240 the nav now opens as a drawer, which is a visible
   change on a small laptop and the correct one — the alternative is a row that does not fit. */
@media (max-width: 1240px) {
    .nav-toggle { display: inline-flex; }
    .nav-links {
        position: absolute;
        top: 100%;
        left: 0; right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        margin: 0;
        padding: 8px 20px 20px;
        background: rgba(0,0,0,0.97);
        border-bottom: 1px solid var(--line-mid);
        backdrop-filter: blur(16px);
        -webkit-backdrop-filter: blur(16px);
        display: none;
    }
    .nav-links.open { display: flex; }
    .nav-links a { padding: 14px 0; font-size: 15px; border-top: 1px solid var(--line); }
    .nav-links a.active::after { left: 0; right: auto; width: 22px; bottom: 8px; }
    .nav-cta { margin: 16px 0 0; }
    .nav-links a.nav-cta { border-top: none; }
}

@media (max-width: 780px) {
    :root { --gut: 20px; }
    .band { padding: 76px 0; }
    .band--tight { padding: 0 0 56px; }
    .hero { padding: 76px 0 64px; }
    .grid-2, .grid-4, .form-row { grid-template-columns: 1fr; }


    .step { grid-template-columns: 1fr; gap: 12px; }
    .step-num { padding-top: 0; }
    .cta-band { padding: 52px 24px; }
    .btn { width: 100%; }
    .btn-row { flex-direction: column; }
    .arrow-link { width: auto; }
}

@media (max-width: 480px) {
    .stats { grid-template-columns: 1fr; }
    .track { padding: 34px 22px 30px; }
    .card { padding: 28px 22px; }
    .form { padding: 24px 20px; }
    .footer-top { grid-template-columns: 1fr; gap: 34px; }
}

/* ===== Calculator =====

   Reuses .field / .form-row / .btn wholesale. What is new here is the two-column
   shell, the result tiles, and the SVG chart.

   One addition to the palette: a loss red. The site is otherwise platinum and a
   single orange accent, and orange is reserved — it is the chart's own line. But
   a profit-and-loss tool that renders a loss in the same colour as a profit is
   withholding the one thing the reader is looking for, so negative numbers get a
   desaturated red. It is semantic state, not a second brand colour, and it
   appears nowhere except on a number that is below zero. */

/* One vertical run: chart, then the numbers it summarises, then the controls
   that produced them. Nothing sits beside anything. */
.calc { display: grid; gap: 40px; }

/* ---- inputs ----
   Full width now, so the groups sit side by side rather than stacking into one
   very long thin form. Flex rather than grid auto-fit on purpose: the number of
   groups changes with the mode (energy adds one), and flex-grow redistributes
   the row to however many are actually showing. auto-fit would size tracks for
   a fixed count and leave half the row empty in machines mode. */
.calc-inputs { display: grid; gap: 26px; border-top: 1px solid var(--line); padding-top: 32px; }

/* Reset and Copy sit together under the columns. Copy holds a minimum width so
   the row does not twitch when its label changes to the confirmation. */
.calc-actions { display: flex; flex-wrap: wrap; gap: 12px; }
#calcCopy { min-width: 16em; }

/* Market / Machine / Operating, side by side as the desk tool has them. A
   fourth column appears in energy mode, so the track count has to follow the
   number of visible groups rather than being fixed — hence flex with grow,
   not a grid with a fixed template. */
.calc-cols { display: flex; flex-wrap: wrap; gap: 24px; align-items: flex-start; }
.calc-cols > .calc-group {
    /* 200, not 270. Energy mode adds a fourth group, and at a 270 basis four
       columns need 1152px inside a 1144px wrap — short by eight pixels, so the
       last group wrapped to its own row and grew to fill it. That is why
       Operating Parameters went full width on the energy tab and stayed a column
       on the machines tab. At 200 both counts fit on one row: three at 365px,
       four at 268px. */
    flex: 1 1 200px;
    min-width: 0;
    border: 1px solid var(--line);
    background: var(--panel);
    padding: 20px;
    align-content: start;
}

/* A unit welded to its input, rather than tucked into the label. Reads faster
   and stops "0.055" ever being ambiguous. */
.calc-unit { display: flex; align-items: stretch; border: 1px solid var(--line-mid); background: var(--panel-solid); }
.calc-unit input { border: none !important; background: transparent !important; flex: 1; min-width: 0; }
.calc-unit input:focus { box-shadow: none !important; }
.calc-unit:focus-within { border-color: var(--btc-300); box-shadow: inset 0 0 0 1px rgba(247,147,26,0.35); }
.cu-pre, .cu-post {
    display: flex; align-items: center; flex: none;
    padding: 0 11px;
    font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em;
    color: var(--plat-500); background: rgba(255,255,255,0.022);
    white-space: nowrap;
}
.cu-pre { border-right: 1px solid var(--line); }
.cu-post { border-left: 1px solid var(--line); }

/* Square switch. Same anatomy as the app — state, title, one line of
   explanation — but no radius, because the site has none anywhere. */
.calc-switch {
    display: flex; gap: 13px; align-items: flex-start; cursor: pointer;
    border: 1px solid var(--line-mid); padding: 13px 14px;
    transition: border-color 0.18s, background 0.18s;
}
.calc-switch:hover { border-color: var(--line-hi); }
.calc-switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.cs-track {
    flex: none; width: 38px; height: 20px; margin-top: 1px;
    border: 1px solid var(--line-hi); background: var(--panel-solid);
    position: relative; transition: background 0.18s, border-color 0.18s;
}
.cs-track::after {
    content: ""; position: absolute; top: 2px; left: 2px;
    width: 14px; height: 14px; background: var(--plat-500);
    transition: transform 0.18s, background 0.18s;
}
.calc-switch input:checked ~ .cs-track { border-color: var(--btc-300); }
.calc-switch input:checked ~ .cs-track::after { transform: translateX(18px); background-image: var(--metal-btc-btn); background-color: var(--btc-300); }
.calc-switch:has(input:checked) { border-color: var(--line-btc); background: rgba(247,147,26,0.045); }
.calc-switch input:focus-visible ~ .cs-track { outline: 2px solid var(--btc-300); outline-offset: 2px; }
.cs-body { display: grid; gap: 4px; }
.cs-title { font-size: 13px; font-weight: 500; color: var(--plat-100); line-height: 1.3; }
.cs-desc { font-size: 11.5px; color: var(--text-dim); line-height: 1.5; }

/* Rates revealed by a switch, stepped in so they read as belonging to it. */
.calc-sub {
    display: grid; gap: 16px;
    border-left: 2px solid var(--line-btc);
    padding: 4px 0 4px 14px;
}
.calc-explain { font-size: 11.5px; line-height: 1.6; color: var(--text-dim); margin: 0; }
.calc-explain strong { color: var(--plat-300); font-weight: 500; }

.calc-modes {
    display: grid;
    grid-template-columns: 1fr 1fr;
    border: 1px solid var(--line-mid);
}
.calc-modes button {
    font-family: var(--mono);
    font-size: 11px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--plat-400);
    background: transparent;
    border: none;
    padding: 14px 10px;
    cursor: pointer;
    transition: color 0.18s, background 0.18s;
}
.calc-modes button + button { border-left: 1px solid var(--line-mid); }
.calc-modes button:hover { color: var(--plat-100); background: var(--panel-hover); }
.calc-modes button[aria-pressed="true"] {
    color: var(--black);
    background-image: var(--metal-btc-btn);
}
.calc-modes button:focus-visible { outline: 2px solid var(--btc-300); outline-offset: -3px; }

.calc-group { display: grid; gap: 16px; }
.calc-group-title {
    font-family: var(--mono);
    font-size: 10.5px;
    font-weight: 500;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--plat-500);
    padding-bottom: 10px;
    border-bottom: 1px solid var(--line);
    margin: 0;
}
.field label small {
    font-size: 9.5px;
    letter-spacing: 0.1em;
    color: var(--plat-500);
    text-transform: none;
}
.calc-hint { font-size: 12px; line-height: 1.65; color: var(--text-dim); margin: -2px 0 0; }
.calc-hint--warn { color: var(--plat-400); border-left: 2px solid var(--line-btc); padding-left: 11px; }
/* Turns green once the two market figures really are live. */
.calc-hint--warn.is-live { border-left-color: var(--gain); }
.calc-hint--warn.is-live strong { color: var(--gain); }

/* Volume -> power -> machines, shown as a chain because that is the order the
   reasoning runs in and each step is one the reader may want to argue with. */
.calc-derived { border: 1px solid var(--line); background: var(--panel); padding: 16px; display: grid; gap: 12px; }
.calc-chain { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.calc-chain > div { display: grid; gap: 3px; }
.cd-lab {
    font-family: var(--mono); font-size: 9px; letter-spacing: 0.18em;
    text-transform: uppercase; color: var(--plat-500);
}
.cd-val { font-family: var(--mono); font-size: 16px; color: var(--plat-100); font-variant-numeric: tabular-nums; }
.cd-sub { font-size: 11px; color: var(--text-dim); }
.cd-arrow { color: var(--btc-300); font-size: 15px; }

.calc-adv-toggle {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    width: 100%;
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.18em;
    text-transform: uppercase; color: var(--plat-300);
    background: transparent; border: 1px solid var(--line-mid);
    padding: 13px 15px; cursor: pointer;
    transition: border-color 0.18s, color 0.18s;
}
.calc-adv-toggle:hover { border-color: var(--line-hi); color: var(--plat-100); }
.calc-adv-toggle svg { transition: transform 0.2s; flex: none; }
.calc-adv-toggle[aria-expanded="true"] svg { transform: rotate(180deg); }
.calc-group--adv { gap: 16px; }

.calc-checks { display: grid; gap: 11px; }
.calc-check { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; font-size: 13px; line-height: 1.5; color: var(--plat-300); }
.calc-check input { flex: none; margin-top: 1px; accent-color: var(--btc-300); width: 15px; height: 15px; }
[data-needs-tax] { transition: opacity 0.2s; }
[data-needs-tax].is-off { opacity: 0.38; }

/* ---- results ---- */

.calc-results { display: grid; gap: 26px; min-width: 0; }

.calc-warn {
    border: 1px solid var(--line-btc);
    background: rgba(247, 147, 26, 0.06);
    color: var(--btc-100);
    padding: 12px 15px;
    font-size: 13px;
    line-height: 1.6;
    margin: 0;
}

.calc-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
.calc-tile { background: var(--surface); padding: 18px 16px; display: grid; gap: 7px; align-content: start; }
.ct-lab {
    font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.17em;
    text-transform: uppercase; color: var(--plat-500);
}
.ct-val {
    font-family: var(--mono); font-size: clamp(19px, 2vw, 25px); font-weight: 500;
    color: var(--plat-100); font-variant-numeric: tabular-nums; line-height: 1.1;
}
.ct-sub { font-size: 11px; color: var(--text-dim); line-height: 1.45; }
.ct-val--btc { color: var(--btc-300); }

.is-up { color: var(--gain); }
.is-down { color: var(--loss); }

/* ---- chart ----
   Two axes: cumulative BTC on the left as bars, net value on the right as
   lines. The app draws Buy & Hold green; here it is platinum, because this
   site runs one accent and orange belongs to mining. The pair are told apart
   by form — solid against dashed, filled against outlined. */
.calc-chart-wrap { border: 1px solid var(--line); background: var(--panel); padding: 18px 18px 14px; display: grid; gap: 14px; }
.calc-chart-title {
    font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0.18em;
    text-transform: uppercase; color: var(--plat-300); margin: 0;
    padding-bottom: 12px; border-bottom: 1px solid var(--line);
}
.calc-plot { position: relative; }
.calc-chart { width: 100%; height: auto; display: block; overflow: visible; }
.calc-chart:focus-visible { outline: 2px solid var(--btc-300); outline-offset: 2px; }

.ck-grid { stroke: var(--line); stroke-width: 1; }
.ck-zero { stroke: var(--line-hi); stroke-width: 1; }
.ck-ylab { fill: var(--plat-400); font-family: var(--mono); font-size: 10.5px; text-anchor: end; dominant-baseline: middle; }
.ck-ylab--r { text-anchor: start; }
.ck-xlab { fill: var(--plat-400); font-family: var(--mono); font-size: 10.5px; text-anchor: middle; }
.ck-axis { fill: var(--plat-500); font-family: var(--mono); font-size: 9.5px; letter-spacing: 0.14em; text-anchor: middle; text-transform: uppercase; }

.ck-bar-mined { fill: rgba(247, 147, 26, 0.62); stroke: none; }
.ck-bar-held  { fill: rgba(229, 228, 226, 0.34); stroke: none; }
.ck-area { fill-opacity: 0.34; }
/* Lines sit over their own gradient areas now, so they carry a little more
   weight and a round cap — a hairline over a filled shape reads as an edge
   rather than as the subject. */
.ck-value  { fill: none; stroke: url(#ckMetalBtc);  stroke-width: 2.6; stroke-linejoin: round; stroke-linecap: round; }
.ck-bench  { fill: none; stroke: url(#ckMetalPlat); stroke-width: 1.7; stroke-dasharray: 6 5; stroke-linecap: round; }
.ck-machines { fill: none; stroke: var(--plat-500); stroke-width: 1.4; stroke-dasharray: 2 3; }
.ck-be { stroke: var(--line-btc); stroke-width: 1; stroke-dasharray: 3 3; }
.ck-halving { stroke: var(--btc-400); stroke-width: 1; stroke-dasharray: 4 4; }
.ck-halvingflag { fill: #0b0b0b; stroke: var(--line-btc); stroke-width: 1; }
.ck-halvinglab { fill: var(--btc-300); font-family: var(--mono); font-size: 8.5px; letter-spacing: 0.12em; text-anchor: middle; }

/* Where each curve ends up, said at the end of it. */
.ck-end-value { fill: url(#ckMetalBtc); }
.ck-end-bench { fill: url(#ckMetalPlat); }
.ck-endlab { font-family: var(--mono); font-size: 11px; dominant-baseline: middle; font-variant-numeric: tabular-nums; }
.ck-end-value-lab { fill: var(--btc-200); }
.ck-end-bench-lab { fill: var(--plat-400); }

/* The readout strip, under the plot rather than over it.

   It began life as a floating tooltip. A tooltip covers the data it describes
   and moves as you track along, so your eye chases it; parked here it holds
   still and occludes nothing. It is always in the document so the row never
   appears and disappears under the pointer, and it carries an idle line rather
   than going blank.

   Fonts are declared rather than inherited: this block was lost once in a slice,
   and an unstyled readout does not vanish, it renders in the browser default
   serif with no ground behind it. */
.calc-readout {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px 34px;
    min-height: 76px;
    padding: 16px 20px;
    border: 1px solid var(--line);
    background: var(--panel);
}
.ct-idle { font-family: var(--sans); font-size: 13.5px; color: var(--text-dim); }
.ct-head {
    font-family: var(--mono);
    font-size: 12px;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--plat-200);
    padding-right: 20px;
    border-right: 1px solid var(--line);
    white-space: nowrap;
}
.ct-item { display: inline-flex; align-items: center; gap: 11px; }
.ct-item .cl-key { width: 12px; height: 12px; }
.ct-body { display: grid; gap: 3px; }
.ct-name {
    font-family: var(--mono);
    /* 10.5px is the floor the README sets for this site; 9.5 would have been
       the smallest type on the page. */
    font-size: 10.5px;
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--plat-500);
    white-space: nowrap;
}
.ct-num {
    font-family: var(--mono);
    font-size: 17px;
    color: var(--plat-100);
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
    white-space: nowrap;
}

/* The invisible columns that carry each period's index for hover.

   These MUST declare a fill. An SVG rect with no fill defaults to opaque black,
   and these are emitted last and tile the entire plot area — so losing this one
   rule paints sixty black rectangles over the whole chart and leaves nothing but
   the axis labels outside it. That is exactly what happened when this block was
   rewritten and these two rules were dropped. */
.ck-hit { fill: transparent; cursor: crosshair; }
.ck-hit:hover { fill: rgba(229, 228, 226, 0.05); }
.ck-cross { stroke: var(--line-hi); stroke-width: 1; pointer-events: none; }

/* A dot per curve at the hovered period, so the crosshair is not left saying
   only which period it is. */
.ck-dot { pointer-events: none; stroke: #0b0b0b; stroke-width: 2; }
.ck-dot--mining   { fill: url(#ckMetalBtc); }
.ck-dot--hold     { fill: url(#ckMetalPlat); }
.ck-dot--machines { fill: var(--plat-500); }
.calc-legend { display: flex; gap: 8px 18px; flex-wrap: wrap; }
.cl-item {
    display: inline-flex; align-items: center; gap: 8px;
    font-size: 11.5px; color: var(--plat-300);
    background: none; border: none; padding: 2px 0; cursor: pointer;
    transition: color 0.18s, opacity 0.18s;
}
.cl-item:hover { color: var(--plat-000); }
.cl-item.is-off { color: var(--text-dim); text-decoration: line-through; opacity: 0.65; }
.cl-item:focus-visible { outline: 2px solid var(--btc-300); outline-offset: 2px; }
.cl-key { width: 11px; height: 11px; flex: none; border: 1px solid transparent; }
/* The legend swatches take the CSS ramps directly; same metal as the chart. */
.cl-key--mining   { background-image: var(--metal-btc-flat); }
.cl-key--hold     { border-color: var(--plat-200); background-image: var(--metal-plat-soft); background-clip: border-box; }
.cl-key--mined    { background-image: var(--metal-btc-flat); opacity: 0.72; }
.cl-key--held     { background-image: var(--metal-plat-flat); opacity: 0.5; }
.cl-key--machines { border-color: var(--plat-500); background: transparent; }
.calc-caption { font-size: 11.5px; color: var(--text-dim); margin: 0; line-height: 1.55; }

/* ---- panels ---- */

.calc-panels { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.calc-panel { border: 1px solid var(--line); background: var(--panel); padding: 18px; display: grid; gap: 13px; align-content: start; }
.calc-panel h3 {
    font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0.18em;
    text-transform: uppercase; color: var(--plat-300); margin: 0;
    padding-bottom: 11px; border-bottom: 1px solid var(--line);
}
.calc-panel dl { display: grid; gap: 9px; margin: 0; }
.calc-panel dl > div { display: flex; justify-content: space-between; align-items: baseline; gap: 14px; }
.calc-panel dt { font-size: 12.5px; color: var(--text-mid); }
.calc-panel dd {
    margin: 0; font-family: var(--mono); font-size: 13px; color: var(--plat-100);
    font-variant-numeric: tabular-nums; text-align: right;
}
.calc-panel dl > div.is-total { border-top: 1px solid var(--line); padding-top: 10px; margin-top: 3px; }
.calc-panel dl > div.is-total dt { color: var(--plat-200); }
.calc-panel dl > div.is-total dd { font-size: 15px; }
.calc-verdict { font-size: 13px; line-height: 1.55; margin: 0; }

/* ---- table ---- */

.calc-table-wrap { border: 1px solid var(--line); background: var(--panel); }
.calc-table-wrap summary {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.18em;
    text-transform: uppercase; color: var(--plat-300);
    padding: 15px 18px; cursor: pointer; list-style: none;
}
.calc-table-wrap summary::-webkit-details-marker { display: none; }
.calc-table-wrap summary::before { content: '+ '; color: var(--btc-300); }
.calc-table-wrap[open] summary::before { content: '\2212  '; }
.calc-table-wrap summary:hover { color: var(--plat-100); }
.calc-table-scroll { overflow-x: auto; }
.calc-table { width: 100%; border-collapse: collapse; font-family: var(--mono); font-size: 11.5px; font-variant-numeric: tabular-nums; }
.calc-table th {
    text-align: right; font-weight: 500; color: var(--plat-500); white-space: nowrap;
    padding: 9px 14px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
    font-size: 9.5px; letter-spacing: 0.13em; text-transform: uppercase;
}
.calc-table th:first-child, .calc-table td:first-child { text-align: left; }
.calc-table td { text-align: right; padding: 8px 14px; color: var(--plat-300); white-space: nowrap; border-bottom: 1px solid rgba(229,228,226,0.05); }
.calc-table tr.is-halving td { background: rgba(247, 147, 26, 0.045); }
.calc-table .tag {
    font-size: 8.5px; letter-spacing: 0.14em; color: var(--btc-300);
    border: 1px solid var(--line-btc); padding: 1px 5px; margin-left: 6px;
}
.calc-table-wrap .calc-caption { padding: 0 18px 15px; }

/* ---- closing note ---- */

.calc-note { display: grid; gap: 26px; }
.calc-note-cols { display: grid; grid-template-columns: repeat(3, 1fr); gap: 30px; }
.calc-note-cols h4 {
    font-family: var(--mono); font-size: 10.5px; font-weight: 500; letter-spacing: 0.17em;
    text-transform: uppercase; color: var(--btc-300); margin: 0 0 10px;
}
.calc-note-cols p { font-size: 14px; line-height: 1.7; color: var(--text-mid); margin: 0; }
.calc-cta { display: flex; gap: 14px; flex-wrap: wrap; }
.calc-head { max-width: 780px; }

@media (max-width: 1020px) {
    .calc { gap: 32px; }
    .calc-panels { grid-template-columns: 1fr; }
    .calc-note-cols { grid-template-columns: 1fr; gap: 26px; }
}
@media (max-width: 660px) {
    .calc-tiles { grid-template-columns: 1fr 1fr; }
}

/* Slider + number box sharing one value. The number box is narrow on purpose:
   it is for typing an exact figure, the slider is for sweeping. */
.calc-pair { display: grid; grid-template-columns: 1fr 74px; gap: 12px; align-items: center; }
.calc-pair input[type="number"] { padding: 9px 8px; text-align: center; font-family: var(--mono); }
.calc-pair input[type="range"] {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 26px;
    background: transparent;
    cursor: ew-resize;
    padding: 0;
    border: none;
}
.calc-pair input[type="range"]::-webkit-slider-runnable-track { height: 4px; background: var(--line-hi); }
.calc-pair input[type="range"]::-moz-range-track           { height: 4px; background: var(--line-hi); }
.calc-pair input[type="range"]::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 13px;
    height: 26px;
    margin-top: -11px;
    border: none;
    border-radius: 0;
    background-image: var(--metal-btc-btn);
}
.calc-pair input[type="range"]::-moz-range-thumb {
    width: 13px;
    height: 26px;
    border: none;
    border-radius: 0;
    background-image: var(--metal-btc-btn);
}
.calc-pair input[type="range"]:focus-visible { outline: 2px solid var(--btc-300); outline-offset: 3px; }

/* How much is in the drawer, said out loud. */
.calc-adv-toggle em {
    font-style: normal;
    color: var(--btc-300);
    margin-left: 8px;
}

/* ---- hardware catalogue ----
   The order summary sits above the table and sticks, so the totals stay in
   view while you are still choosing. It is not a cart: nothing persists and
   nothing is charged, because we source per order rather than holding stock. */
.hw { display: grid; gap: 30px; }

.hw-order {
    position: sticky;
    top: 0;
    z-index: 4;
    border: 1px solid var(--line-mid);
    background: #0b0b0b;
    padding: 18px 20px;
    display: grid;
    gap: 14px;
}
.hw-totals { display: flex; flex-wrap: wrap; gap: 14px 40px; }
.hw-totals > div { display: grid; gap: 5px; }
.hw-totals .ct-val { font-size: clamp(18px, 2vw, 23px); }
.hw-actions { display: flex; flex-wrap: wrap; gap: 12px; }

.hw-cat { display: grid; gap: 22px; }

/* Grouped by maker so a long catalogue has landmarks. */
/* The catalogue is a table again. Cards gave each machine a large section but
   twenty-eight of them is a very long page, and the job here is comparison —
   reading J/TH and price down a column, which a list does and a stack of cards
   does not. The spacing is where the cards' benefit is kept: roughly double the
   row padding of the shared .calc-table, so the rows breathe. */
.hw-table { font-size: 12px; }
/* 16px across, not 22. Three economics columns took the table from seven
   columns to ten and 1255px into a 1144px container — 111px over, which put
   "Run the numbers" almost entirely past the right edge. Six pixels a side on
   ten columns is 120px back, which is the whole overflow. */
.hw-table th { padding: 14px 16px; }
.hw-table td { padding: 16px 16px; vertical-align: middle; }

/* AND THE LAST COLUMN IS PINNED, so it is reachable at any width rather than
   only at the widths where the table happens to fit. Below 1200px the container
   shrinks and the overflow comes back; the padding above fixes the common case,
   this fixes every other one.

   The background is opaque black because it has to be: a sticky cell that lets
   the scrolling cells show through it is worse than no sticky cell at all. Black
   is exact here — body is the only opaque background above this table, and it is
   #000. The rule is written against the token rather than the literal so a
   future theme change moves both together. */
.hw-table th:last-child,
.hw-table td.hw-see {
    position: sticky;
    right: 0;
    z-index: 2;
    background: var(--black);
}
/* A hairline so the pinned column reads as pinned rather than as a cell that
   happens to be there, and only while there is actually something behind it. */
.hw-table th:last-child::before,
.hw-table td.hw-see::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    width: 1px;
    background: var(--line);
}
.hw-table td, .hw-table th { white-space: nowrap; }
.hw-table .hw-name { text-align: left; color: var(--plat-100); font-size: 13.5px; letter-spacing: 0.01em; }
.hw-table .hw-price { color: var(--btc-200); }
.hw-noprice { color: var(--text-dim); font-style: italic; }

/* A row with machines on it lights up, so a long list still shows what has been
   picked without scrolling back to the summary. Keyed on the value ATTRIBUTE,
   which is why setQty() in hardware.js writes it as well as the property — a
   version that sets only .value keeps every total right and never lights a row. */
.hw-table tr:has(input[data-qty]:not([value="0"])) .hw-name { color: var(--btc-200); }

.hw-see a { font-size: 12px; color: var(--plat-400); }

/* --- the daily economics columns ---

   Right-aligned and tabular so a column of money can be compared down its own
   length: proportional digits put the decimal points in different places on
   every row, which is the whole reason tabular-nums exists. */
.hw-table .hw-num {
    text-align: right;
    font-variant-numeric: tabular-nums;
}
.hw-table th.hw-num { text-align: right; }

/* A machine losing money at the entered power price says so in the loss colour
   rather than quietly showing a number with a minus in front of it. That is the
   single most useful thing this table can tell somebody: at your power price,
   this one does not work. */
.hw-table .hw-loss { color: var(--loss); }

/* The power-price control sits above the table rather than in it — it applies
   to every row, and a control repeated per row would read as a per-row setting. */
.hw-econ {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 14px 28px;
    margin-bottom: 4px;
}
.hw-econ .field { min-width: 190px; }
.hw-econ .calc-hint { flex: 1 1 320px; margin: 0 0 6px; }

/* Only ever added once both figures actually arrived, so it means what it says. */
.hw-live { color: var(--gain); }
.hw-see a:hover { color: var(--btc-300); }

/* The quantity control, kept from the card version. It is the site's own input
   anatomy — a .calc-unit with .cu-pre / .cu-post affix chips — not a bespoke
   widget. What it replaced was a bare number field carrying the browser's
   spinner arrows, the one control on this site the browser drew rather than the
   stylesheet. .hw-step adds only the button reset and the hover; the edge, the
   ground, the chip colour and the focus ring all come from rules the calculator
   already owns, so the two cannot drift apart. */
.hw-qty { width: 1%; }
.hw-qty .calc-unit { display: inline-flex; }
.hw-qty input {
    width: 4em;
    text-align: center;
    font-family: var(--mono); font-size: 13px;
    color: var(--plat-100);
    padding: 7px 4px;
    font-variant-numeric: tabular-nums;
    /* The chips are the stepper, so the browser's own arrows would be a second
       one. Removed here only — the calculator keeps its native spinners. */
    -moz-appearance: textfield;
    appearance: textfield;
}
.hw-qty input::-webkit-outer-spin-button,
.hw-qty input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

.hw-step {
    -webkit-appearance: none; appearance: none;
    border: 0; padding: 0 13px; cursor: pointer;
    font-size: 13px; line-height: 1;
    transition: color 0.15s, background 0.15s;
}
/* .cu-pre / .cu-post carry the divider at (0,1,0); these win at (0,2,0) rather
   than relying on being later in the file. */
.cu-pre.hw-step { border-right: 1px solid var(--line); }
.cu-post.hw-step { border-left: 1px solid var(--line); }
.hw-step:hover { color: var(--plat-100); background: var(--panel-hover); }
.hw-step:focus-visible { outline: 2px solid var(--btc-300); outline-offset: -2px; }

.hw-send { display: grid; gap: 16px; }
.hw-preview {
    font-family: var(--mono);
    font-size: 12px;
    line-height: 1.65;
    color: var(--plat-200);
    background: var(--panel);
    border: 1px solid var(--line);
    padding: 16px 18px;
    margin: 0;
    white-space: pre-wrap;
    overflow-x: auto;
}
.hw-preview.is-empty { color: var(--text-dim); font-style: italic; }
.hw-send .btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* ---- the order, carried between pages ---- */

/* The nav badge. Sized off the CTA beside it rather than given a shape of its
   own, and it only exists when the order does — cart.js keeps it hidden at
   zero, so the nav is seven items again the moment the order is emptied. */
/* Every one of these is selected as .nav-links a.nav-cart, not .nav-cart. The
   badge is an <a> inside .nav-links, so ".nav-links a" is (0,1,1) and beats a
   bare class at (0,1,0) — the first version of this rendered at the nav link's
   own padding and 15px type, which is what pushed the nav into wrapping. It is
   the same trap .nav-cta already carries a note about. */
.nav-links a.nav-cart {
    display: inline-flex; align-items: center; gap: 7px;
    font-family: var(--mono); font-size: 10px; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--plat-300);
    border: 1px solid var(--line-mid); padding: 6px 9px;
    margin-left: 10px;
    white-space: nowrap;
    transition: border-color 0.18s, color 0.18s;
}
.nav-links a.nav-cart::after { display: none; }
.nav-links a.nav-cart:hover { color: var(--btc-300); border-color: var(--line-btc); }

/* The producer portal, as a ghost button beside the primary CTA.

   IT USED TO BE PLAIN MONO TEXT, deliberately: the note here said a second
   bordered box beside the CTA turns the right-hand end of the nav into three
   competing rectangles, counting the order badge. That was a real observation
   and it is the cost of this change — the badge is hidden at zero, so the
   three-box case is only a visitor mid-order, but it is a case.

   The trade is reach. A producer who has been sent a link to a statement is
   looking for a way in, and a text link between the nav items is not where an
   eye goes for one. Ghost rather than primary keeps the hierarchy: one filled
   button on the page, and this reading as the second thing.

   THE GEOMETRY IS RESTATED HERE FOR THE SAME REASON THE CTA RESTATES ITS OWN.
   .nav-links a is (0,1,1) and .btn / .btn--sm are (0,1,0), so the nav wins
   padding, font-size, letter-spacing and colour. Background, border and
   text-transform are NOT set by .nav-links a, so those reach it from .btn and
   .btn--ghost untouched — which is why only these four appear below. Font-size
   and letter-spacing are deliberately left to the nav so this matches the CTA
   beside it rather than .btn--sm. */
.nav-links a.nav-signin {
    padding: 9px 15px 7px;
    color: var(--plat-100);
    margin-left: 10px;
    white-space: nowrap;
    flex-shrink: 0;
}
.nav-links a.nav-signin:focus-visible { color: var(--plat-000); }
.nav-links a.nav-signin::after { display: none; }
.nav-links a.nav-signin:hover { color: var(--plat-000); }
.nav-cart-n {
    font-size: 10.5px; letter-spacing: 0; color: var(--black);
    background-image: var(--metal-btc-btn);
    padding: 1px 6px; min-width: 18px; text-align: center;
    font-variant-numeric: tabular-nums;
}

/* ---- the checkout ---- */

.ck-empty { display: grid; gap: 16px; justify-items: start; max-width: 60ch; }

/* The line table is the catalogue table with a money column, so it inherits
   .hw-table wholesale and only says what differs. */
.ck-table .hw-price { color: var(--plat-100); }
.ck-drop { width: 1%; }
.ck-remove {
    -webkit-appearance: none; appearance: none;
    border: 0; background: none; cursor: pointer;
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.13em;
    text-transform: uppercase; color: var(--plat-500);
    padding: 4px 2px;
    transition: color 0.15s;
}
.ck-remove:hover { color: var(--loss); }
.ck-remove:focus-visible { outline: 2px solid var(--btc-300); outline-offset: 1px; }

/* The deposit split sits under the totals and above the caveat, because the
   order of reading is what it costs, what you pay now, what is left. Ruled off
   rather than boxed: it is the same figure divided, not a second summary. */
.ck-split {
    display: flex; flex-wrap: wrap; gap: 14px 44px;
    border-top: 1px solid var(--line);
    padding-top: 15px;
}
.ck-split-part { display: grid; gap: 5px; }
.ck-split .ct-val { font-size: clamp(18px, 2vw, 23px); }

/* The demo banner. Loud on purpose and pinned to the top of the page: this is
   the one message that must not be missed, because everything below it is
   pretending. Not the loss colour — nothing is wrong, it is just not real. */
.demo-flag {
    position: sticky; top: 0; z-index: 200;
    margin: 0;
    padding: 11px 20px;
    font-family: var(--mono); font-size: 11.5px; line-height: 1.55;
    letter-spacing: 0.02em;
    color: var(--black);
    background-image: var(--metal-btc-flat);
    text-align: center;
}
.demo-flag strong { font-weight: 600; }

/* ---- paying, and following an order ---- */

.pay { display: grid; gap: 30px; }
.pay-rail { display: grid; gap: 12px; border: 1px solid var(--line); padding: 20px 22px; }
.pay-rail-title {
    font-family: var(--mono); font-size: 10.5px; font-weight: 500;
    letter-spacing: 0.17em; text-transform: uppercase;
    color: var(--btc-300); margin: 0;
}

/* The address is the authoritative thing on the page and the one a mistake
   cannot be undone on, so it is set larger than anything else and grouped into
   fours. Breaking anywhere is deliberate: a long address that overflows its box
   is worse than one that wraps. */
.pay-addr {
    font-family: var(--mono);
    font-size: clamp(15px, 2.1vw, 20px);
    line-height: 1.7; letter-spacing: 0.04em;
    color: var(--plat-100);
    background: var(--panel-solid);
    border: 1px solid var(--line-mid);
    padding: 14px 16px; margin: 0;
    word-break: break-all;
}
/* The Lightning invoice is long, secondary, and nobody reads it — it is here to
   be copied, so it is sized to fit rather than to be legible. */
.pay-bolt {
    font-family: var(--mono); font-size: 11px; line-height: 1.6;
    color: var(--plat-300);
    background: var(--panel-solid);
    border: 1px solid var(--line);
    padding: 12px 14px; margin: 0;
    word-break: break-all;
    max-height: 96px; overflow-y: auto;
}

/* One line that is always true about the payment. Colour carries the state as
   well as the words, since this is the thing a customer stares at. */
.pay-state {
    font-family: var(--mono); font-size: 12.5px; line-height: 1.6;
    border-left: 3px solid var(--line-mid);
    padding: 12px 16px; margin: 0;
    color: var(--plat-300);
}
.pay-state[data-state="waiting"] { border-left-color: var(--btc-300); color: var(--btc-200); }
.pay-state[data-state="unknown"] { border-left-color: var(--plat-500); }
.pay-state[data-state="expired"] { border-left-color: var(--loss); color: var(--loss); }

.pay-problem, .pay-done { display: grid; gap: 14px; max-width: 68ch; }
.pay-done {
    border: 1px solid var(--line-btc);
    box-shadow: inset 3px 0 0 0 var(--btc-300);
    background: var(--panel-solid);
    padding: 22px 24px;
}

/* Picking a rail. Built from the same parts as the calculator mode switch,
   so it reads as the same kind of control rather than a new one. */
.pay-rails { display: flex; flex-wrap: wrap; border: 1px solid var(--line-mid); }
.pay-rail-pick {
    -webkit-appearance: none; appearance: none;
    flex: 1 1 auto; min-width: 120px;
    border: 0; border-right: 1px solid var(--line);
    padding: 13px 18px; cursor: pointer;
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--plat-400); background: var(--panel-solid);
    transition: color 0.16s, background 0.16s;
}
.pay-rail-pick:last-child { border-right: 0; }
.pay-rail-pick:hover { color: var(--plat-100); background: var(--panel-hover); }
.pay-rail-pick.is-on { color: var(--black); background-image: var(--metal-btc-flat); }
.pay-rail-pick:focus-visible { outline: 2px solid var(--btc-300); outline-offset: -2px; }

/* Bank details. Laid out as label/value pairs in mono, because every one of
   them is a string somebody has to copy exactly. */
.pay-bank { display: grid; gap: 9px; margin: 0; }
.pay-bank > div { display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: baseline; }
.pay-bank dt {
    flex: 0 0 150px;
    font-family: var(--mono); font-size: 10px; letter-spacing: 0.15em;
    text-transform: uppercase; color: var(--plat-500);
}
.pay-bank dd {
    margin: 0; flex: 1 1 200px;
    font-family: var(--mono); font-size: 13.5px; color: var(--plat-100);
    word-break: break-all;
}
.pay-ref-label {
    font-family: var(--mono); font-size: 10px; letter-spacing: 0.15em;
    text-transform: uppercase; color: var(--btc-300); margin: 4px 0 0;
}

/* ---- the order lifecycle ---- */

.ord-flow { display: grid; gap: 14px; }
.ord-steps { list-style: none; margin: 0; padding: 0; display: grid; }
.ord-step {
    display: flex; align-items: baseline; justify-content: space-between; gap: 20px;
    padding: 12px 0 12px 22px;
    border-bottom: 1px solid rgba(229,228,226,0.05);
    position: relative;
    font-size: 13.5px;
}
/* A square marker, because the site has no radii anywhere. Filled for done,
   accented for the step in progress, hollow for what has not happened. */
.ord-step::before {
    content: ''; position: absolute; left: 0; top: 17px;
    width: 9px; height: 9px;
    border: 1px solid var(--line-hi);
}
.ord-step.is-done::before { background: var(--plat-400); border-color: var(--plat-400); }
.ord-step.is-now::before { background-image: var(--metal-btc-flat); border-color: var(--btc-300); }
.ord-step.is-done { color: var(--plat-300); }
.ord-step.is-now { color: var(--plat-100); }
.ord-step.is-todo { color: var(--plat-500); }
.ord-step.is-cancelled { color: var(--loss); }
.ord-step.is-cancelled::before { background: var(--loss); border-color: var(--loss); }
.ord-step-label { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.ord-step-when {
    font-family: var(--mono); font-size: 10.5px; letter-spacing: 0.08em;
    color: var(--plat-500); white-space: nowrap;
}
/* The steps that are a person. Labelled rather than disguised — see order.js. */
.ord-step-ours {
    font-family: var(--mono); font-size: 9px; letter-spacing: 0.16em;
    text-transform: uppercase; color: var(--plat-500);
    border: 1px solid var(--line-mid); padding: 2px 6px;
}

/* The order landed. The reference is the customer's only handle on it, so it
   is set at display size and in mono, where a transposed character is visible. */
.ck-placed {
    display: grid; gap: 12px;
    border: 1px solid var(--line-btc);
    box-shadow: inset 3px 0 0 0 var(--btc-300);
    background: var(--panel-solid);
    padding: 20px 22px;
}
.ck-ref {
    font-family: var(--mono);
    font-size: clamp(19px, 2.6vw, 26px);
    letter-spacing: 0.06em;
    color: var(--btc-200);
    margin: 0;
    word-break: break-all;
}

/* The checkout summary does not follow the page: the form is directly below it
   and a sticky block would sit on top of the fields being filled in. */
.ck-order { position: static; }

@media (max-width: 720px) {
    .hw-order { position: static; }
}
