/* Erupted Hosting: flat, high-contrast, content-first.
   Dark by default, light when the system asks for it, and either one when the visitor picks it (data-theme on <html>).
   Colors, fonts and radii come from brand/BRAND.md and brand/tokens/tokens.css: dark maps to the brand's Ink ground,
   light maps to its Paper ground, and Lava/Ink text stays constant on buttons regardless of theme (see brand/BRAND.md,
   "Primary buttons use Ink text, not white"). */

/* The brand's two typefaces (brand/BRAND.md), served from this site rather than Google Fonts, so no visitor's address is sent to
   Google just to draw a page. The files are Google's own woff2 builds: Sora is one variable file covering the 500-700 weights,
   IBM Plex Mono one file per weight. Each comes as a latin and a latin-ext part, and the browser fetches only the parts the
   text on the page needs. swap: text is drawn in the fallback font first instead of staying invisible while a font loads. */
@font-face {
  font-family: 'Sora'; font-style: normal; font-weight: 100 800; font-display: swap;
  src: url(/fonts/sora-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Sora'; font-style: normal; font-weight: 100 800; font-display: swap;
  src: url(/fonts/sora-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap;
  src: url(/fonts/ibm-plex-mono-400-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 400; font-display: swap;
  src: url(/fonts/ibm-plex-mono-400-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url(/fonts/ibm-plex-mono-500-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'IBM Plex Mono'; font-style: normal; font-weight: 500; font-display: swap;
  src: url(/fonts/ibm-plex-mono-500-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* Every colour on the site comes from these tokens. Dark is the default; the light values are listed twice below (once for
   "follow the system", once for the visitor picking Light), because CSS has no way to share one block between the two. */
:root, :root[data-theme="dark"] {
  color-scheme: dark;
  --bg: #111318;        /* Ink */
  --surface: #1e2129;   /* Ink, raised */
  --raised: color-mix(in srgb, var(--surface), white 10%);
  --field: #111318;
  --line: #262931;      /* divider on Ink */
  --line-2: #3a3d46;    /* outline-button border on Ink */
  --text: #f6f4f1;      /* Paper, used as text on dark */
  --muted: #a3a2ab;     /* secondary text on Ink, 7.4:1 */
  --accent: #ff4b26;    /* Lava: backgrounds, buttons, graphics */
  --accent-hover: color-mix(in srgb, var(--accent), white 15%);
  --accent-fg: #111318; /* Ink text on a Lava button, 5.6:1 */
  --accent-text: #ffb020; /* Ember: links/labels/eyebrows on dark, 10.2:1 */
  --ok: #22a45d;
  --warn: #ffb020;
  --bad: #f2546f;       /* brand Outage #E5254B is 4.2:1 on Ink, too low for small text; same hue, lifted to 5.6:1 */
  --info: #5aa9ff;
  --serious: #ff8a3d;
  --star: #ffb020;
  --series-1: #ff4b26;
  --series-2: #5aa9ff;
  --rack: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160%22%20height%3D%2264%22%3E%3Crect%20x%3D%220%22%20y%3D%228%22%20width%3D%22120%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%2320232B%22%2F%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2218%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3Canimate%20attributeName%3D%22opacity%22%20values%3D%221%3B.15%3B1%22%20dur%3D%222.6s%22%20begin%3D%22-0.9s%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3Crect%20x%3D%2240%22%20y%3D%2240%22%20width%3D%22112%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%2320232B%22%2F%3E%3Ccircle%20cx%3D%2252%22%20cy%3D%2250%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3Canimate%20attributeName%3D%22opacity%22%20values%3D%221%3B.15%3B1%22%20dur%3D%223.4s%22%20begin%3D%22-2.1s%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3C%2Fsvg%3E"); /* rack stripes for the foot of a page, lights blinking (BRAND.md: Patterns and graphics) */
  --rack-still: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160%22%20height%3D%2264%22%3E%3Crect%20x%3D%220%22%20y%3D%228%22%20width%3D%22120%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%2320232B%22%2F%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2218%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3C%2Fcircle%3E%3Crect%20x%3D%2240%22%20y%3D%2240%22%20width%3D%22112%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%2320232B%22%2F%3E%3Ccircle%20cx%3D%2252%22%20cy%3D%2250%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3C%2Fcircle%3E%3C%2Fsvg%3E");
  --rack-ink: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160%22%20height%3D%2264%22%3E%3Crect%20x%3D%220%22%20y%3D%228%22%20width%3D%22120%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%2320232B%22%2F%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2218%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3Canimate%20attributeName%3D%22opacity%22%20values%3D%221%3B.15%3B1%22%20dur%3D%222.6s%22%20begin%3D%22-0.9s%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3Crect%20x%3D%2240%22%20y%3D%2240%22%20width%3D%22112%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%2320232B%22%2F%3E%3Ccircle%20cx%3D%2252%22%20cy%3D%2250%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3Canimate%20attributeName%3D%22opacity%22%20values%3D%221%3B.15%3B1%22%20dur%3D%223.4s%22%20begin%3D%22-2.1s%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3C%2Fsvg%3E"); /* the same on an Ink ground in either theme (the home hero, .edge-rack) */
  --rack-ink-still: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160%22%20height%3D%2264%22%3E%3Crect%20x%3D%220%22%20y%3D%228%22%20width%3D%22120%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%2320232B%22%2F%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2218%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3C%2Fcircle%3E%3Crect%20x%3D%2240%22%20y%3D%2240%22%20width%3D%22112%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%2320232B%22%2F%3E%3Ccircle%20cx%3D%2252%22%20cy%3D%2250%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3C%2Fcircle%3E%3C%2Fsvg%3E");
  --volcano: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20560%20420%22%3E%3Cpath%20d%3D%22M280%208C304%2044%20336%2068%20336%20104C336%20134%20311%20152%20280%20152C249%20152%20224%20134%20224%20104C224%2080%20238%2066%20248%2054C252%2068%20262%2076%20268%2076C274%2048%20272%2028%20280%208Z%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%22150%22%20cy%3D%2280%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%22420%22%20cy%3D%2248%22%20r%3D%227%22%20fill%3D%22%23FFB020%22%2F%3E%3Ccircle%20cx%3D%22384%22%20cy%3D%22128%22%20r%3D%226%22%20fill%3D%22%23FF4B26%22%2F%3E%3Crect%20x%3D%22186%22%20y%3D%22176%22%20width%3D%22188%22%20height%3D%2260%22%20rx%3D%2220%22%20fill%3D%22%232b3039%22%2F%3E%3Crect%20x%3D%22120%22%20y%3D%22260%22%20width%3D%22320%22%20height%3D%2260%22%20rx%3D%2220%22%20fill%3D%22%232b3039%22%2F%3E%3Crect%20x%3D%2254%22%20y%3D%22344%22%20width%3D%22452%22%20height%3D%2260%22%20rx%3D%2220%22%20fill%3D%22%232b3039%22%2F%3E%3Ccircle%20cx%3D%22230%22%20cy%3D%22206%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%22164%22%20cy%3D%22290%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%2298%22%20cy%3D%22374%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Crect%20x%3D%22290%22%20y%3D%22286%22%20width%3D%22110%22%20height%3D%228%22%20rx%3D%224%22%20fill%3D%22%233d4350%22%2F%3E%3Crect%20x%3D%22290%22%20y%3D%22370%22%20width%3D%22170%22%20height%3D%228%22%20rx%3D%224%22%20fill%3D%22%233d4350%22%2F%3E%3C%2Fsvg%3E"); /* the volcano bars, drawn large, for the FAQ's empty corner */
  --dots-accent: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22120%22%20height%3D%2296%22%3E%3Ccircle%20cx%3D%2284%22%20cy%3D%2236%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3C%2Fcircle%3E%3Ccircle%20cx%3D%2236%22%20cy%3D%2284%22%20r%3D%222.5%22%20fill%3D%22%23FFB020%22%3E%3C%2Fcircle%3E%3C%2Fsvg%3E"); /* the lava and ember dots scattered through the ember-dot pattern */
  --dots-accent-anim: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22120%22%20height%3D%2296%22%3E%3Ccircle%20cx%3D%2284%22%20cy%3D%2236%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3Canimate%20attributeName%3D%22opacity%22%20values%3D%221%3B.15%3B1%22%20dur%3D%223.8s%22%20begin%3D%22-1.3s%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3Ccircle%20cx%3D%2236%22%20cy%3D%2284%22%20r%3D%222.5%22%20fill%3D%22%23FFB020%22%3E%3Canimate%20attributeName%3D%22opacity%22%20values%3D%221%3B.15%3B1%22%20dur%3D%225.1s%22%20begin%3D%22-3.4s%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3C%2Fsvg%3E"); /* the same, twinkling, for the short strips along a section's edge */
  --band: color-mix(in srgb, #111318, #1e2129 75%); /* alternate section ground, lifted off Ink */
  --ghost-border: #3a3d46;
  --shadow-header: none;
  --sidebar-bg: #1e2129;
  --on-bad: #111318;   /* text on a --bad fill: white is only 3.4:1 on the lifted red */
  --band-accent-text: #ffb020;
  --shadow: 0 30px 60px -24px rgba(17, 19, 24, .6);
  --shadow-sm: 0 1px 3px rgba(17, 19, 24, .4);
  --ring: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);

  --radius-lg: 28px;   /* large panels */
  --radius: 20px;      /* cards, boxes, dialogs */
  --radius-btn: 8px;   /* buttons and fields. Owner preference: tighter than the brand guide's 12px (see CLAUDE.md) */
  --radius-sm: 6px;    /* tags and small chips */
  --max: 1280px;      /* brand: 1280-1440 wide layouts with 64px gutters */
  --sidebar: 248px;    /* the Portal's side menu on wide screens */
  --sans: 'Sora', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Consolas, monospace;
}

@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --bg: #f6f4f1;        /* Paper */
    --surface: #ffffff;   /* card background on Paper */
    --raised: #ece8e2;    /* Stone */
    --field: #f6f4f1;     /* Paper fill */
    --line: #e4dfd8;      /* card border on light */
    --line-2: #d9d3ca;    /* section divider on light */
    --text: #111318;      /* Ink */
    --muted: #5a5961;     /* muted body text on light, 6.9:1 */
    --accent: #ff4b26;    /* Lava, same as dark: button colour never changes with theme */
    --accent-hover: color-mix(in srgb, var(--accent), black 10%); /* Ink text stays above 4.5:1 (4.6:1) */
    --accent-fg: #111318; /* Ink text on a Lava button, 5.6:1 */
    --accent-text: #c93517; /* Deep Lava: links/small accent text on light, 4.8:1 */
    --ok: #117c57;
    --warn: #9a5800;
    --bad: #c62828;
    --info: #1f6fc9;
    --serious: #c2560a;
    --star: #b97000;      /* gold that still reads on white: 3.9:1 (stars are graphics, need 3:1) */
    --series-1: #c93517;
    --series-2: #1f6fc9;
    --rack: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160%22%20height%3D%2264%22%3E%3Crect%20x%3D%220%22%20y%3D%228%22%20width%3D%22120%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%23E4DFD8%22%2F%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2218%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3Canimate%20attributeName%3D%22opacity%22%20values%3D%221%3B.15%3B1%22%20dur%3D%222.6s%22%20begin%3D%22-0.9s%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3Crect%20x%3D%2240%22%20y%3D%2240%22%20width%3D%22112%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%23E4DFD8%22%2F%3E%3Ccircle%20cx%3D%2252%22%20cy%3D%2250%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3Canimate%20attributeName%3D%22opacity%22%20values%3D%221%3B.15%3B1%22%20dur%3D%223.4s%22%20begin%3D%22-2.1s%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3C%2Fsvg%3E"); /* rack stripes for the foot of a page, lights blinking (BRAND.md: Patterns and graphics) */
    --rack-still: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160%22%20height%3D%2264%22%3E%3Crect%20x%3D%220%22%20y%3D%228%22%20width%3D%22120%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%23E4DFD8%22%2F%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2218%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3C%2Fcircle%3E%3Crect%20x%3D%2240%22%20y%3D%2240%22%20width%3D%22112%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%23E4DFD8%22%2F%3E%3Ccircle%20cx%3D%2252%22%20cy%3D%2250%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3C%2Fcircle%3E%3C%2Fsvg%3E");
    --volcano: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20560%20420%22%3E%3Cpath%20d%3D%22M280%208C304%2044%20336%2068%20336%20104C336%20134%20311%20152%20280%20152C249%20152%20224%20134%20224%20104C224%2080%20238%2066%20248%2054C252%2068%20262%2076%20268%2076C274%2048%20272%2028%20280%208Z%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%22150%22%20cy%3D%2280%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%22420%22%20cy%3D%2248%22%20r%3D%227%22%20fill%3D%22%23FFB020%22%2F%3E%3Ccircle%20cx%3D%22384%22%20cy%3D%22128%22%20r%3D%226%22%20fill%3D%22%23FF4B26%22%2F%3E%3Crect%20x%3D%22186%22%20y%3D%22176%22%20width%3D%22188%22%20height%3D%2260%22%20rx%3D%2220%22%20fill%3D%22%23DCD5CB%22%2F%3E%3Crect%20x%3D%22120%22%20y%3D%22260%22%20width%3D%22320%22%20height%3D%2260%22%20rx%3D%2220%22%20fill%3D%22%23DCD5CB%22%2F%3E%3Crect%20x%3D%2254%22%20y%3D%22344%22%20width%3D%22452%22%20height%3D%2260%22%20rx%3D%2220%22%20fill%3D%22%23DCD5CB%22%2F%3E%3Ccircle%20cx%3D%22230%22%20cy%3D%22206%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%22164%22%20cy%3D%22290%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%2298%22%20cy%3D%22374%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Crect%20x%3D%22290%22%20y%3D%22286%22%20width%3D%22110%22%20height%3D%228%22%20rx%3D%224%22%20fill%3D%22%23C9C1B6%22%2F%3E%3Crect%20x%3D%22290%22%20y%3D%22370%22%20width%3D%22170%22%20height%3D%228%22%20rx%3D%224%22%20fill%3D%22%23C9C1B6%22%2F%3E%3C%2Fsvg%3E"); /* the volcano bars, drawn large, for the FAQ's empty corner */
    --band: #ece8e2;      /* Stone: alternate section ground */
    --ghost-border: #111318;
    --sidebar-bg: #111318;
    --on-bad: #ffffff;
    --band-accent-text: color-mix(in srgb, #c93517 88%, #111318); /* Deep Lava is 4.3:1 on Stone; nudged toward Ink: 5:1 */
    --shadow-header: 0 8px 24px rgba(17, 19, 24, .06);
    --shadow: 0 30px 60px -28px rgba(17, 19, 24, .2);
    --shadow-sm: 0 1px 3px rgba(17, 19, 24, .1);
  }
}
/* The visitor's own choice, from the appearance switch (see common.js). It wins over the system setting either way. */
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f6f4f1;
  --surface: #ffffff;
  --raised: #ece8e2;
  --field: #f6f4f1;
  --line: #e4dfd8;
  --line-2: #d9d3ca;
  --text: #111318;
  --muted: #5a5961;
  --accent: #ff4b26;
  --accent-hover: color-mix(in srgb, var(--accent), black 10%); /* Ink text stays above 4.5:1 (4.6:1) */
  --accent-fg: #111318;
  --accent-text: #c93517;
  --ok: #117c57;
  --warn: #9a5800;
  --bad: #c62828;
  --info: #1f6fc9;
  --serious: #c2560a;
  --star: #b97000;
  --series-1: #c93517;
  --series-2: #1f6fc9;
  --rack: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160%22%20height%3D%2264%22%3E%3Crect%20x%3D%220%22%20y%3D%228%22%20width%3D%22120%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%23E4DFD8%22%2F%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2218%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3Canimate%20attributeName%3D%22opacity%22%20values%3D%221%3B.15%3B1%22%20dur%3D%222.6s%22%20begin%3D%22-0.9s%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3Crect%20x%3D%2240%22%20y%3D%2240%22%20width%3D%22112%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%23E4DFD8%22%2F%3E%3Ccircle%20cx%3D%2252%22%20cy%3D%2250%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3Canimate%20attributeName%3D%22opacity%22%20values%3D%221%3B.15%3B1%22%20dur%3D%223.4s%22%20begin%3D%22-2.1s%22%20repeatCount%3D%22indefinite%22%2F%3E%3C%2Fcircle%3E%3C%2Fsvg%3E"); /* rack stripes for the foot of a page, lights blinking (BRAND.md: Patterns and graphics) */
  --rack-still: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22160%22%20height%3D%2264%22%3E%3Crect%20x%3D%220%22%20y%3D%228%22%20width%3D%22120%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%23E4DFD8%22%2F%3E%3Ccircle%20cx%3D%2212%22%20cy%3D%2218%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3C%2Fcircle%3E%3Crect%20x%3D%2240%22%20y%3D%2240%22%20width%3D%22112%22%20height%3D%2220%22%20rx%3D%227%22%20fill%3D%22%23E4DFD8%22%2F%3E%3Ccircle%20cx%3D%2252%22%20cy%3D%2250%22%20r%3D%223%22%20fill%3D%22%23FF4B26%22%3E%3C%2Fcircle%3E%3C%2Fsvg%3E");
  --volcano: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%20560%20420%22%3E%3Cpath%20d%3D%22M280%208C304%2044%20336%2068%20336%20104C336%20134%20311%20152%20280%20152C249%20152%20224%20134%20224%20104C224%2080%20238%2066%20248%2054C252%2068%20262%2076%20268%2076C274%2048%20272%2028%20280%208Z%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%22150%22%20cy%3D%2280%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%22420%22%20cy%3D%2248%22%20r%3D%227%22%20fill%3D%22%23FFB020%22%2F%3E%3Ccircle%20cx%3D%22384%22%20cy%3D%22128%22%20r%3D%226%22%20fill%3D%22%23FF4B26%22%2F%3E%3Crect%20x%3D%22186%22%20y%3D%22176%22%20width%3D%22188%22%20height%3D%2260%22%20rx%3D%2220%22%20fill%3D%22%23DCD5CB%22%2F%3E%3Crect%20x%3D%22120%22%20y%3D%22260%22%20width%3D%22320%22%20height%3D%2260%22%20rx%3D%2220%22%20fill%3D%22%23DCD5CB%22%2F%3E%3Crect%20x%3D%2254%22%20y%3D%22344%22%20width%3D%22452%22%20height%3D%2260%22%20rx%3D%2220%22%20fill%3D%22%23DCD5CB%22%2F%3E%3Ccircle%20cx%3D%22230%22%20cy%3D%22206%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%22164%22%20cy%3D%22290%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Ccircle%20cx%3D%2298%22%20cy%3D%22374%22%20r%3D%229%22%20fill%3D%22%23FF4B26%22%2F%3E%3Crect%20x%3D%22290%22%20y%3D%22286%22%20width%3D%22110%22%20height%3D%228%22%20rx%3D%224%22%20fill%3D%22%23C9C1B6%22%2F%3E%3Crect%20x%3D%22290%22%20y%3D%22370%22%20width%3D%22170%22%20height%3D%228%22%20rx%3D%224%22%20fill%3D%22%23C9C1B6%22%2F%3E%3C%2Fsvg%3E"); /* the volcano bars, drawn large, for the FAQ's empty corner */
  --band: #ece8e2;
  --ghost-border: #111318;
  --sidebar-bg: #111318;
  --on-bad: #ffffff;
  --band-accent-text: color-mix(in srgb, #c93517 88%, #111318);
  --shadow-header: 0 8px 24px rgba(17, 19, 24, .06);
  --shadow: 0 30px 60px -28px rgba(17, 19, 24, .2);
  --shadow-sm: 0 1px 3px rgba(17, 19, 24, .1);
}

/* ---------- Grounds ----------
   brand/BRAND.md: "Pick one ground: Ink, Paper or Lava." A section, panel or header with .ground-ink is Ink in either
   theme: it re-declares the color tokens for everything inside it, so buttons, links, cards and the logo inside it pick
   the dark-ground versions without needing their own rules. Used for the front-page hero and its header, the "Included"
   band, the footer, and (in light mode) the Portal's side menu - the contrast between grounds is what gives each page its
   structure. Lava stays a plain background (.cta-band); everything on it is Ink. */
.ground-ink {
  color-scheme: dark;
  --bg: #111318; --surface: #1e2129; --raised: color-mix(in srgb, #1e2129, white 10%); --field: #111318;
  --line: #262931; --line-2: #3a3d46; --ghost-border: #3a3d46;
  --text: #f6f4f1; --muted: #a3a2ab; --accent-text: #ffb020;
  --ok: #22a45d; --warn: #ffb020; --bad: #f2546f; --info: #5aa9ff; --serious: #ff8a3d; --star: #ffb020; --on-bad: #111318;
  --shadow: 0 30px 60px -24px rgba(0, 0, 0, .6); --shadow-sm: 0 1px 3px rgba(0, 0, 0, .4); --shadow-header: none;
  background-color: var(--bg); color: var(--text);
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scroll-padding-top: 100px; background: var(--bg); }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3 { font-weight: 650; line-height: 1.15; letter-spacing: -.02em; margin: 0 0 .5em; }
p { margin: 0 0 1em; }
a { color: inherit; }
ul { margin: 0; padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }
button, :where(input, select, textarea) { font: inherit; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
::selection { background: color-mix(in srgb, var(--accent) 40%, transparent); }

/* Every text box, dropdown and text area on the site. :where() keeps this weak, so a component only states what differs
   (a width, a monospace font); the look itself is defined here once. */
:where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="submit"], [type="button"], [type="hidden"], [type="color"]), select, textarea) {
  background: var(--field); color: var(--text); border: 1.5px solid var(--line-2); border-radius: var(--radius-btn);
  padding: .75rem 1rem; font-weight: 400; line-height: 1.4; transition: border-color .15s, box-shadow .15s;
}
/* brand: inputs use IBM Plex Mono at 14px. Not below 16px on phones: iOS zooms the page into any smaller field. */
:where(input:not([type="checkbox"], [type="radio"], [type="range"], [type="file"], [type="submit"], [type="button"], [type="hidden"], [type="color"])) { font-family: var(--mono); font-size: .875rem; }
@media (max-width: 760px) { :where(input:not([type="checkbox"], [type="radio"])) { font-size: 1rem; } }
:where(input, select, textarea)::placeholder { color: var(--muted); opacity: .8; }
:where(input:not([type="checkbox"], [type="radio"]), select, textarea):hover:not(:disabled, :focus) { border-color: color-mix(in srgb, var(--muted) 60%, var(--line-2)); }
input:not([type="checkbox"], [type="radio"]):focus, select:focus, textarea:focus { outline: none; border-color: var(--accent); box-shadow: var(--ring); }
:where(input, select, textarea):disabled { opacity: .6; cursor: not-allowed; }
:where(select) { cursor: pointer; }
:where(textarea) { resize: vertical; }
:where(input[type="checkbox"], input[type="radio"]) { accent-color: var(--accent); }
input[type="number"] { -moz-appearance: textfield; }
.mono { font-family: var(--mono); }

.container { width: 100%; max-width: var(--max); margin: 0 auto; padding: 0 clamp(20px, 5vw, 64px); } /* brand: 64px gutters on desktop, 16-24 on phones */
.container.narrow { max-width: 760px; }
.muted { color: var(--muted); font-size: .88rem; margin: 0; }
.hint { color: var(--muted); font-size: .85rem; }
.hint a { color: inherit; text-underline-offset: 3px; }
.hint a:hover { color: var(--accent-text); }
.note { color: var(--muted); font-size: .95rem; margin: 1.5rem 0 0; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .4rem;
  min-height: 44px; padding: .65rem 1.35rem; border-radius: var(--radius-btn);
  border: 1.5px solid var(--accent); background: var(--accent); color: var(--accent-fg);
  font: 600 .95rem var(--sans); text-decoration: none; cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, transform .08s ease-out;
}
.btn:hover { background: var(--accent-hover); border-color: var(--accent-hover); }
.btn-ghost { background: transparent; color: var(--text); border-color: var(--ghost-border); }
.btn-ghost:hover { background: var(--raised); border-color: var(--ghost-border); }
.btn-small { min-height: 36px; padding: .35rem .85rem; font-size: .86rem; }
.btn-lg { min-height: 52px; padding: .85rem 1.6rem; font-size: 1rem; }
.btn-block { display: flex; width: 100%; }
.btn:active:not(:disabled) { transform: scale(.97); }
@media (prefers-reduced-motion: reduce) { .btn { transition: background .15s, border-color .15s, color .15s; } .btn:active:not(:disabled) { transform: none; } }
.btn:disabled { opacity: .55; cursor: not-allowed; }
.btn[hidden] { display: none; }
.btn svg { width: 1.05em; height: 1.05em; flex: none; }

/* ---------- Nav ---------- */
.nav {
  position: sticky; top: 0; z-index: 50;
  /* brand: the white header with a #E4DFD8 border and the header shadow, for inner pages and the scrolled state */
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
  box-shadow: var(--shadow-header);
  transition: background-color .2s, box-shadow .2s, border-color .2s;
}
/* The dark header, over the front page's Ink hero (script.js drops .ground-ink once the hero has scrolled away). */
.nav.ground-ink { background: var(--bg); }
.nav-inner { display: flex; align-items: center; justify-content: space-between; height: 88px; gap: 1.5rem; }
/* The real lockup (brand/BRAND.md says never redraw or retype the wordmark), swapped for the light- or dark-background
   version to match whichever theme is active - same three-block pattern as the color tokens above. */
.logo { display: inline-flex; align-items: center; text-decoration: none; }
.logo-img { height: 28px; width: auto; }
.logo-light { display: none; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .logo-light { display: block; }
  :root:not([data-theme="dark"]) .logo-dark { display: none; }
}
:root[data-theme="light"] .logo-light { display: block; }
:root[data-theme="light"] .logo-dark { display: none; }
/* On an Ink ground the reversed logo, whatever the theme (after the rules above: same specificity, so order decides). */
:root .ground-ink .logo-light { display: none; }
:root .ground-ink .logo-dark { display: block; }
.nav-links { display: flex; align-items: center; gap: 1.75rem; }
.nav-links a:not(.btn) { text-decoration: none; color: var(--muted); font-size: .93rem; transition: color .15s, transform .08s ease-out; }
.nav-links a:not(.btn):hover, .nav-links a[aria-current="page"] { color: var(--text); }
.nav-links a:not(.btn):active { transform: scale(.96); }
.nav-links a[aria-current="page"] { color: var(--text); box-shadow: 0 2px 0 var(--accent); padding-bottom: 3px; }
/* The marked link stays level with the others: the 3px under it would otherwise lift its text as the mark arrives. */
@media (min-width: 761px) { .nav-links:not([data-account-nav]) a[aria-current] { margin-bottom: -3px; } }
.nav-links[data-account-nav] { gap: 1.3rem; }
.nav-links[hidden], .nav-links a[hidden] { display: none; }
.menu-toggle { display: none; background: none; border: 0; padding: 8px; margin-right: -8px; cursor: pointer; transition: transform .08s ease-out; }
.menu-toggle:active { transform: scale(.9); }
.menu-toggle span { display: block; width: 22px; height: 2px; background: var(--text); margin: 5px 0; transition: transform .2s, opacity .2s; }
.menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---------- Hero ---------- */
/* Always on the Ink ground (.ground-ink in the HTML), like the brand's website board. */
.hero { position: relative; overflow: hidden; padding: 80px 0 104px; border-bottom: 1px solid var(--line); }
/* The copy on the left, the example control panel on the right. */
.hero-inner { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr); gap: 56px; align-items: center; }
/* brand hero headline: Sora 700, -0.04em, 1.02 (a little under the 72-76px of the board, so this longer line stays at three lines) */
.hero h1 { font-size: clamp(2.5rem, 4.6vw, 4rem); font-weight: 700; letter-spacing: -.04em; line-height: 1.02; margin-bottom: .45em; }
.hl { color: var(--accent-text); }
.hero .hl { color: var(--accent); } /* Lava as large headline text on Ink: 5.5:1, allowed at 24px and up */
.lead { color: var(--muted); font-size: 1.15rem; max-width: 46ch; margin-bottom: 2rem; }
.hero-cta { display: flex; gap: .875rem; flex-wrap: wrap; }
/* What every plan comes with, each behind a lava status light like the ones on the mark's server bars. */
.hero-points { display: grid; grid-template-columns: repeat(2, max-content); gap: .8rem 2.5rem; margin-top: 2.5rem; padding-top: 1.5rem; border-top: 1px solid var(--line); font: .8125rem/1.4 var(--mono); color: var(--muted); }
.hero-points li { display: inline-flex; align-items: center; gap: .6rem; }
.hero-points li::before { content: ''; width: 7px; height: 7px; flex: none; border-radius: 50%; background: var(--accent); }

/* The brand eyebrow: IBM Plex Mono caps above a headline. Ember on Ink, Deep Lava on Paper (both via --accent-text). */
.kicker { margin: 0 0 1.25rem; font: 500 .8125rem/1.2 var(--mono); letter-spacing: .16em; text-transform: uppercase; color: var(--accent-text); }

/* decorative control-panel preview, with a "paid" toast overlapping its corner */
.hero-visual { position: relative; }
.mock-toast {
  position: absolute; left: -28px; bottom: -22px; display: flex; align-items: center; gap: .6rem;
  background: var(--text); color: var(--bg); border-radius: 10px; padding: .65rem 1rem; font-size: .85rem; font-weight: 500;
  box-shadow: var(--shadow);
}
.mock-toast b { display: grid; place-items: center; width: 20px; height: 20px; border-radius: 50%; background: var(--ok); color: #111318; font-size: .7rem; }
.mock-toast small { font: .72rem var(--mono); opacity: .65; }
@media (max-width: 560px) { .hero-points { grid-template-columns: minmax(0, 1fr); } }

/* decorative control-panel preview */
.mock { background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius-lg); box-shadow: var(--shadow); overflow: hidden; }
.mock-bar { display: flex; align-items: center; gap: .4rem; padding: .7rem 1rem; border-bottom: 1px solid var(--line); background: var(--raised); }
.mock-bar i { width: 10px; height: 10px; border-radius: 50%; background: var(--line-2); }
.mock-title { margin-left: .6rem; font: .75rem var(--mono); color: var(--muted); }
.mock-tag { margin-left: auto; font: .68rem var(--mono); color: var(--muted); border: 1px solid var(--line-2); border-radius: 4px; padding: 0 .4rem; }
.mock-body { padding: 1.25rem; }
.mock-head { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.2rem; }
.mock-head strong { display: block; font-size: 1.05rem; }
.mock-head small { color: var(--muted); font: .75rem var(--mono); }
.mock-status { display: inline-flex; align-items: center; gap: .4rem; font: 500 .72rem var(--mono); color: var(--ok); border: 1px solid currentColor; border-radius: 4px; padding: .12rem .5rem; }
.mock-status::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.meters { display: grid; gap: .75rem; margin-bottom: 1.2rem; }
.meter { display: grid; grid-template-columns: 56px 1fr 104px; align-items: center; gap: .75rem; font: .75rem var(--mono); color: var(--muted); }
.meter em { font-style: normal; text-align: right; color: var(--text); }
.bar { height: 6px; border-radius: 3px; background: var(--line); }
.bar span { display: block; height: 100%; border-radius: 3px; background: var(--accent); }
.w-8 { width: 8%; } .w-12 { width: 12%; } .w-38 { width: 38%; }

/* products that aren't open for ordering yet */
.hero-note { margin: 1.75rem 0 0; font: .82rem var(--mono); color: var(--muted); }
.hero-note b { color: var(--ok); font-weight: 500; }
.tab.soon::after { content: 'soon'; margin-left: .45rem; padding: 0 .3rem; border: 1px solid var(--line-2); border-radius: 4px; font: 500 .65rem var(--mono); color: var(--muted); vertical-align: middle; }
.soon-btn { display: inline-flex; align-items: center; justify-content: center; padding: .65rem 1.15rem; border: 1px dashed var(--line-2); border-radius: var(--radius-btn); color: var(--muted); font: 600 .9rem var(--sans); white-space: nowrap; }
.service.soon { opacity: .55; }
.service.soon:hover { border-color: var(--line); }
.service.soon .service-label { color: var(--muted); }
.soon-note { margin: 0; font: 500 .85rem var(--mono); color: var(--muted); }
.mock-console { margin: 0 0 1.2rem; padding: .9rem 1rem; border-radius: 8px; background: #0a0a0c; color: #c4c4cc; font: .74rem/1.75 var(--mono); white-space: pre-wrap; }
.mock-console .t { color: #6f6f7a; }
.mock-console .ok { color: #3ecf8e; }
.mock-actions { display: flex; gap: .5rem; }
.mock-actions span { font: 500 .78rem var(--sans); padding: .35rem .85rem; border: 1px solid var(--line-2); border-radius: 6px; }
.mock-actions span:first-child { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }


/* ---------- Sections ---------- */
.section { position: relative; padding: 96px 0; }
/* Alternate sections sit on a second ground (Stone on light, a lifted Ink on dark), so consecutive sections read as
   separate blocks instead of one long page. White cards on Stone keep their edges. */
.section.alt { background: var(--band); border-block: 1px solid var(--line); --accent-text: var(--band-accent-text); }
/* brand: one pattern, at one edge, never behind text. A strip inside the section padding (the content starts below
   it), fading out towards the middle: rack stripes along the top of an Ink band, the flame field along the bottom of
   the Lava band. The patterns are the brand kit's own tiles (brand/source/elements.html). */
.section > .container, .cta-band > .container { position: relative; }
.edge-rack::before, .edge-flames::before { content: ''; position: absolute; left: 0; right: 0; height: 64px; pointer-events: none; }
.edge-rack::before { top: 0; background: var(--rack-ink) left top repeat-x; -webkit-mask-image: linear-gradient(to left, #000, transparent 75%); mask-image: linear-gradient(to left, #000, transparent 75%); }
.edge-flames { position: relative; }
/* The volcano bars (the mark's server bars, drawn large and cropped off the edge) in a section's bottom-left corner, faded
   towards the content. Only where a section leaves that corner empty (the FAQ). */
.edge-volcano { position: relative; overflow: hidden; }
.edge-volcano > * { position: relative; }
.edge-volcano::before {
  content: ''; position: absolute; left: -60px; bottom: -50px; width: 600px; height: 450px; pointer-events: none;
  background: var(--volcano) no-repeat left bottom / 600px auto; opacity: .75;
  -webkit-mask-image: linear-gradient(to top right, #000 15%, transparent 65%); mask-image: linear-gradient(to top right, #000 15%, transparent 65%);
}
@media (max-width: 760px) { .edge-volcano::before { width: 380px; height: 285px; background-size: 380px auto; } }
.edge-flames::before { bottom: 0; background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='48' height='48'%3E%3Cpath transform='translate(-12 2) scale(0.4)' d='M60 4C66 13 74 19 74 28C74 35.5 67.8 40 60 40C52.2 40 46 35.5 46 28C46 22 49.5 18.5 52 15.5C53 19 55.5 21 57 21C58.5 14 58 9 60 4Z' fill='%23E33F1C'/%3E%3Cpath transform='translate(12 26) scale(0.4)' d='M60 4C66 13 74 19 74 28C74 35.5 67.8 40 60 40C52.2 40 46 35.5 46 28C46 22 49.5 18.5 52 15.5C53 19 55.5 21 57 21C58.5 14 58 9 60 4Z' fill='%23E33F1C'/%3E%3C/svg%3E") left bottom repeat-x; -webkit-mask-image: linear-gradient(to right, #000, transparent 70%); mask-image: linear-gradient(to right, #000, transparent 70%); }
@media (max-width: 760px) { .edge-rack::before, .edge-flames::before { height: 40px; } }

/* Ember dots (brand: "on Paper"): a dot grid with the odd lava and ember spark, as a strip along the top or bottom edge of a
   section, inside its padding so it never runs behind text. The grey dots follow the theme; the sparks are brand colours. */
.edge-dots-top::after {
  content: ''; position: absolute; left: 0; right: 0; height: 72px; pointer-events: none;
  background: var(--dots-accent-anim) 0 0 / 120px 96px, radial-gradient(circle, var(--dot, var(--line-2)) 1.6px, transparent 2.2px) 0 0 / 24px 24px;
}
/* On the darker Stone band the grey dots need a shade more to show. */
.section.alt { --dot: color-mix(in srgb, var(--line-2), var(--text) 18%); }
.edge-dots-top::after { top: 12px; -webkit-mask-image: linear-gradient(to left, #000, transparent 65%); mask-image: linear-gradient(to left, #000, transparent 65%); }
@media (max-width: 760px) { .edge-dots-top::after { height: 48px; top: 6px; } }

/* The hero: a soft lava glow behind the example panel, and rack stripes along its bottom edge. */
.hero > .container { position: relative; z-index: 1; }
.hero::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(640px 460px at 76% 48%, rgba(255, 75, 38, .16), transparent 70%); }
.hero::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 64px; pointer-events: none; background: var(--rack-ink) left top repeat-x; -webkit-mask-image: linear-gradient(to right, #000, transparent 70%); mask-image: linear-gradient(to right, #000, transparent 70%); }
@media (max-width: 760px) { .hero::after { height: 40px; } }
/* brand section head (see the brand boards): mono eyebrow and a 44px headline on the left, the description on the right,
   a rule underneath. */
.section-head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 28rem); column-gap: 3rem; align-items: end; margin-bottom: 2.75rem; padding-bottom: 1.75rem; border-bottom: 1px solid var(--line-2); }
.section-head > * { grid-column: 1; }
.section-head > p:not(.kicker) { grid-column: 2; grid-row: 1 / span 2; }
/* (.section-head p would otherwise win and make the eyebrow body-sized and grey) */
.section-head p.kicker { margin: 0 0 .9rem; font: 500 .8125rem/1.2 var(--mono); color: var(--accent-text); }
.section-head h2 { font-size: clamp(1.9rem, 3.6vw, 2.75rem); font-weight: 700; letter-spacing: -.03em; line-height: 1.05; margin: 0; }
.section-head p { color: var(--muted); margin: 0; font-size: 1.05rem; line-height: 1.55; }
@media (max-width: 760px) { .section-head { grid-template-columns: minmax(0, 1fr); } .section-head > p:not(.kicker) { grid-column: 1; grid-row: auto; margin-top: .9rem; } }

.services { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1.25rem; }
.service {
  position: relative; display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1.75rem; transition: border-color .15s, transform .2s ease, box-shadow .2s ease;
}
/* a short lava strip along the top, like the Portal's service cards */
.service::before { content: ''; position: absolute; top: -1px; left: 1.75rem; right: 1.75rem; height: 3px; border-radius: 0 0 3px 3px; background: var(--accent); }
.service.soon::before { background: var(--line-2); }
.service:hover { border-color: var(--accent); transform: translateY(-3px); box-shadow: 0 18px 40px -24px rgba(17, 19, 24, .35); }
@media (prefers-reduced-motion: reduce) { .service:hover { transform: none; } }
/* brand icon tile: the product's line icon in Ink on a Stone square (brand/source/elements.html). Added by script.js. */
.service-ico { display: grid; place-items: center; width: 56px; height: 56px; margin-bottom: 1.4rem; border-radius: 16px; background: color-mix(in srgb, var(--accent) 12%, var(--raised)); color: var(--accent); }
.service-ico svg { width: 26px; height: 26px; }
.service.soon .service-ico { background: var(--raised); color: var(--muted); }
.service-label { margin: 0 0 .5rem; font: 500 .75rem/1.2 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--accent-text); }
.service h3 { font-size: 1.35rem; }
/* The title leads to the product's own page; it reads as a heading until hovered. */
.service h3 a { text-decoration: none; }
.service h3 a:hover { text-decoration: underline; text-underline-offset: 3px; }
.service p { color: var(--muted); }
/* what you get, as the same dotted list the plan cards use */
.service-facts { display: grid; gap: .5rem; margin: 0 0 1.5rem; padding: 1rem 0 0; list-style: none; border-top: 1px dashed var(--line-2); font: .84rem/1.5 var(--mono); color: var(--text); }
.service-facts li { display: flex; align-items: center; gap: .65rem; }
.service-facts li::before { content: ''; width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--accent); }
.service.soon .service-facts { color: var(--muted); }
.service-foot { margin-top: auto; display: flex; justify-content: space-between; align-items: center; gap: 1rem; }
.service-foot p { margin: 0; }
.from { color: var(--muted); font-size: .9rem; }
.from strong { color: var(--text); font-size: 1.7rem; font-weight: 700; letter-spacing: -.03em; margin: 0 .1rem 0 .25rem; }

/* ---------- Pricing ---------- */
.tabs { display: flex; gap: 1.75rem; border-bottom: 1px solid var(--line); margin: 0 0 1.75rem; }
.tab {
  background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; padding: .6rem 0;
  color: var(--muted); font: 500 .95rem var(--sans); cursor: pointer; transition: color .15s;
}
.tab:hover { color: var(--text); }
.tab.active { color: var(--text); border-bottom-color: var(--accent); }
.panel[hidden] { display: none; }

/* One card per plan, up to four across. The popular plan is an Ink card with a lava edge. */
.plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 230px), 1fr)); gap: 1rem; }
.plans > .note { grid-column: 1 / -1; margin: 0; padding: 1.5rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
.plan-card {
  position: relative; display: flex; flex-direction: column; gap: 1.2rem; padding: 1.6rem 1.5rem 1.5rem;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  transition: border-color .15s, transform .2s ease, box-shadow .2s ease;
}
.plan-card:hover { border-color: var(--line-2); transform: translateY(-3px); box-shadow: 0 18px 40px -26px rgba(17, 19, 24, .45); }
.plan-card.featured { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent), 0 24px 50px -28px rgba(255, 75, 38, .6); }
.plan-card.featured:hover { border-color: var(--accent); }
.plan-card.soon { opacity: .55; }
.plan-card.soon:hover { transform: none; box-shadow: none; }
@media (prefers-reduced-motion: reduce) { .plan-card:hover { transform: none; } }
.plan-head { display: flex; align-items: center; justify-content: space-between; gap: .5rem; min-height: 28px; }
.plan-head h3 { margin: 0; font-size: 1.15rem; }
/* brand tag: IBM Plex Mono 12px 500 uppercase, 28px tall, 6px radius, Lava with Ink text */
.tag { display: inline-block; font: 500 .75rem/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; background: var(--accent); color: var(--accent-fg); border-radius: var(--radius-sm); padding: .5rem .625rem; margin-top: .3rem; }
.plan-head .tag { margin: 0; }
.plan-price { display: flex; align-items: baseline; gap: .2rem; margin: 0; padding-bottom: 1.2rem; border-bottom: 1px solid var(--line); }
.plan-price strong { font-size: 2.5rem; font-weight: 700; letter-spacing: -.035em; line-height: 1; }
.plan-price span { color: var(--muted); font-size: .9rem; }
/* each spec behind a lava status light, like the mark's server bars */
.specs { display: grid; gap: .65rem; margin: 0 0 .4rem; padding: 0; list-style: none; font: .86rem/1.4 var(--mono); color: var(--text); }
.specs li { display: flex; align-items: center; gap: .65rem; }
.specs li::before { content: ''; width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--accent); }
.plan-card > .btn, .plan-card > .soon-btn { width: 100%; margin-top: auto; }
.plan-note { color: var(--muted); font-size: .9rem; margin: 1rem 0 0; max-width: 70ch; }

/* ---------- Features (bento) ---------- */
.bento { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; }
.tile { display: flex; flex-direction: column; min-height: 230px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.6rem; transition: border-color .15s; }
.tile:not(.accent, .invert):hover { border-color: var(--line-2); }
.tile.wide { grid-column: span 2; }
/* the number and name of the point on the left, its icon on a tile on the right; the heading sits at the foot */
.tile-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; margin: 0 0 auto; padding-bottom: 1.5rem; }
.tile-label { font: 500 .75rem var(--mono); color: var(--muted); margin: 0; padding-top: .6rem; }
.tile-ico { display: grid; place-items: center; flex: none; width: 40px; height: 40px; border-radius: 10px; background: color-mix(in srgb, var(--accent) 12%, var(--raised)); color: var(--accent); }
.tile-ico svg { width: 20px; height: 20px; }
.tile.accent .tile-ico { background: color-mix(in srgb, var(--accent-fg) 14%, transparent); color: var(--accent-fg); }
.tile.invert .tile-ico { background: color-mix(in srgb, var(--accent) 12%, var(--text)); color: var(--accent); }
.tile h3 { font-size: 1.2rem; margin-bottom: .4rem; }
.tile p { color: var(--muted); font-size: .94rem; margin: 0; max-width: 42ch; }
.tile.accent { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }
.tile.accent h3 { font-size: clamp(1.6rem, 2.6vw, 2.1rem); font-weight: 700; letter-spacing: -.03em; line-height: 1.08; max-width: 16ch; }
.tile.accent .tile-label, .tile.accent p, .tile.invert .tile-label, .tile.invert p { color: inherit; }
.tile.invert { background: var(--text); border-color: var(--text); color: var(--bg); }
.tile.invert h3 { font-size: clamp(1.5rem, 2.4vw, 1.9rem); font-weight: 700; letter-spacing: -.03em; }
.chips { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: 1.25rem; }
.chips li { font: 500 .76rem var(--mono); padding: .25rem .6rem; border: 1px solid color-mix(in srgb, var(--bg) 35%, transparent); border-radius: 4px; }

/* ---------- FAQ ---------- */
.faq-layout { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.7fr); gap: 2rem 5rem; align-items: start; }
.faq-layout .section-head { display: block; position: sticky; top: 120px; margin: 0; padding: 0; border: 0; }
.faq-layout .section-head p:not(.kicker) { margin-top: 1rem; }
.faq-layout .section-head a { color: var(--text); font-weight: 600; text-underline-offset: 3px; }
@media (max-width: 900px) { .faq-layout { grid-template-columns: minmax(0, 1fr); } .faq-layout .section-head { position: static; } }
.faq { border-top: 1px solid var(--line-2); }
.faq:last-of-type { border-bottom: 1px solid var(--line-2); }
.faq summary { padding: 1.25rem 0; cursor: pointer; font-weight: 600; font-size: 1.05rem; list-style: none; display: flex; justify-content: space-between; gap: 1rem; }
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: '+'; font: 400 1.3rem/1 var(--mono); color: var(--muted); }
.faq[open] summary::after { content: '\2212'; }
.faq p { color: var(--muted); margin: 0 0 1.2rem; max-width: 60ch; }

/* ---------- Contact ---------- */
.cta-band { background: var(--accent); color: var(--accent-fg); padding: 96px 0; }
.cta-inner { display: grid; grid-template-columns: 1fr 1fr; gap: 4rem; align-items: center; }
.cta-band h2 { font-size: clamp(2rem, 4.6vw, 3.3rem); font-weight: 700; letter-spacing: -.035em; line-height: 1.04; max-width: 12ch; }
.cta-copy > p:not(.kicker) { font-size: 1.1rem; max-width: 42ch; }
.cta-band .kicker { color: var(--accent-fg); } /* brand: on Lava, everything is Ink */
.contact-links { display: grid; gap: .3rem; margin-top: 1.5rem; }
.contact-links a { color: inherit; font-weight: 600; text-decoration: none; border-bottom: 2px solid currentColor; width: fit-content; }
.cta-band :focus-visible { outline-color: currentColor; }
.form-card { background: var(--bg); color: var(--text); border-radius: var(--radius-lg); padding: 1.9rem; box-shadow: 0 34px 70px -28px rgba(0, 0, 0, .5); }
.form-card :focus-visible { outline-color: var(--accent); }

.form { display: grid; gap: 1rem; }
.form label { display: grid; gap: .35rem; font-size: .86rem; font-weight: 500; }
.form input, .form select, .form textarea { width: 100%; }
.form :where(input, textarea).invalid { border-color: var(--bad); box-shadow: 0 0 0 1px var(--bad); }
.form[hidden] { display: none; }
.form-status { margin: 0; min-height: 1.4em; font-size: .9rem; color: var(--muted); }
.form-status.bad { color: var(--bad); }
/* An empty status line takes no room, so a form's button sits right under its last field. */
.form .form-status:empty, .acct-form .form-status:empty, .form-body .form-status:empty { display: none; }

/* ---------- Footer ---------- */
/* brand/source/web.html: always on Ink (.ground-ink in the HTML). The logo, a line about us and the social link, then four
   link columns under Ember mono headings, then a bottom bar with the copyright and the system status link. */
.footer { padding: 64px 0 32px; color: var(--muted); font-size: .94rem; }
.footer-top { display: grid; grid-template-columns: minmax(0, 2fr) repeat(4, minmax(0, 1fr)); gap: 2.5rem 2rem; margin-bottom: 3rem; }
.footer h2 { margin: 0 0 1.1rem; font: 500 .75rem/1.2 var(--mono); text-transform: uppercase; letter-spacing: .14em; color: var(--accent-text); }
/* The gap between links is the links' own padding, so each one is a comfortable 31px tall to tap, not 19px. */
.footer li a { display: inline-block; padding: .375rem 0; }
.footer a { color: var(--muted); text-decoration: none; transition: color .15s; }
.footer a:hover { color: var(--text); }
.footer-brand .logo-img { height: 34px; }
.footer-brand p { max-width: 34ch; margin: 1.25rem 0 0; line-height: 1.6; }
.footer-social { display: flex; gap: .6rem; }
.footer-social:not(:has(a:not([hidden]))) { display: none; }
.footer .footer-social a { display: inline-flex; align-items: center; min-height: 44px; padding: 0 1rem; border: 1px solid var(--line-2); border-radius: 10px; color: var(--text); font: .8125rem var(--mono); }
.footer .footer-social a:hover { border-color: var(--muted); }
.footer-bottom { display: flex; justify-content: space-between; align-items: center; gap: 1rem 1.5rem; flex-wrap: wrap; border-top: 1px solid var(--line); padding-top: 1.5rem; font-size: .8125rem; }
.footer-bottom p { margin: 0; }
.footer-bottom-end { display: flex; align-items: center; gap: 1rem 1.75rem; flex-wrap: wrap; }
.footer-status { display: inline-flex; align-items: center; gap: .6rem; font-family: var(--mono); }

/* ---------- Cards, badges, tables (account pages) ---------- */
.card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.5rem; }

/* A status: a tinted pill with a dot, in the colour of what it means. Also used for small labels (.pill). */
.badge, .pill {
  display: inline-flex; align-items: center; gap: .4rem; padding: .16rem .6rem; border-radius: 999px; vertical-align: middle;
  border: 1px solid color-mix(in srgb, currentColor 32%, transparent); background: color-mix(in srgb, currentColor 11%, transparent);
  font: 600 .7rem/1.5 var(--mono); text-transform: uppercase; letter-spacing: .04em; white-space: nowrap; color: var(--muted);
}
/* brand status pill: a colored dot next to an Ink label (status colors are not text-safe as small text on white). */
.badge { --tone: var(--muted); color: var(--text); border-color: color-mix(in srgb, var(--tone) 40%, var(--line)); background: color-mix(in srgb, var(--tone) 12%, transparent); }
.badge::before { content: ''; width: .5rem; height: .5rem; flex: none; border-radius: 50%; background: var(--tone); }
.pill { text-transform: none; letter-spacing: 0; font-weight: 500; }
/* The small uppercase label above a value or a group. One size and spacing everywhere. */
.stat-label, .field-label, .facts-grid dt, .inv-label, .pref-head, .tl-day, .st-day h3, .eyebrow {
  font: 500 .72rem/1.4 var(--mono); letter-spacing: .06em; text-transform: uppercase; color: var(--muted);
}
.badge-active, .badge-paid { --tone: var(--ok); }
.badge-pending, .badge-open, .badge-disputed { --tone: var(--warn); }
.badge-past_due, .badge-failed, .badge-suspended { --tone: var(--bad); }
.badge-cancelled, .badge-void, .badge-refunded { --tone: var(--muted); }

.table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); margin-bottom: 1.5rem; }
.table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.table th { text-align: left; padding: .75rem 1rem; color: var(--muted); font-weight: 500; font-size: .8rem; border-bottom: 1px solid var(--line); white-space: nowrap; }
.table td { padding: .85rem 1rem; border-bottom: 1px solid var(--line); vertical-align: top; }
.table tr:last-child td { border-bottom: 0; }
.table input[type=text], .table input[type=number], .table select, .table textarea { width: 100%; min-width: 110px; padding: .4rem .55rem; }
.table textarea { min-width: 220px; }
.table input[type=checkbox], .check input { width: 17px; height: 17px; }
.row-review td { background: color-mix(in srgb, var(--bad) 8%, transparent); }
.ref { word-break: break-all; max-width: 200px; }
.inv-links { white-space: nowrap; }
.row-actions { display: flex; gap: .5rem; flex-wrap: wrap; }

.banner {
  --dot: var(--accent);
  background: var(--raised); border: 1px solid var(--line-2);
  border-radius: var(--radius-sm); padding: .75rem 1rem .75rem 2.15rem; margin: 1rem 0; font-size: .93rem;
}
.banner-error { --dot: var(--bad); }
/* What kind of message a box is, is said by a dot beside its first line (the brand guide's way of showing state), in the
   box's --dot colour. .8em is half a line of its text. */
.banner, .toast, .review-status { position: relative; }
.banner::before, .toast::before, .review-status::before { content: ''; position: absolute; left: 1rem; top: calc(.8rem + .8em - 4px); width: 8px; height: 8px; border-radius: 50%; background: var(--dot); }
.banner[hidden] { display: none; }

/* ---------- Login ---------- */
.auth-split { display: grid; grid-template-columns: 1fr 1fr; min-height: calc(100vh - 88px); }
/* The login page's left panel: an Ink ground like the front page's hero (.ground-ink in the HTML) - the pitch at the top,
   the brand's volcano bars on the bottom edge, a soft lava glow behind. */
.auth-side { position: relative; overflow: hidden; display: flex; flex-direction: column; justify-content: space-between; gap: 2.5rem; padding: 88px 64px 0; background: var(--bg); color: var(--text); }
.auth-side::before { content: ''; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(560px 420px at 60% 100%, rgba(255, 75, 38, .18), transparent 70%); }
.auth-copy { position: relative; }
.auth-side h2 { font-size: clamp(2.2rem, 3.8vw, 3.25rem); font-weight: 700; letter-spacing: -.04em; line-height: 1.02; max-width: 12ch; margin: 0 0 .5em; }
.auth-side .hl { color: var(--accent); } /* Lava as large text on Ink */
.auth-side p:not(.kicker) { font-size: 1.05rem; max-width: 38ch; margin: 0; color: var(--muted); }
.auth-side .hero-points { margin-top: 2rem; }
.auth-volcano { position: relative; display: block; width: min(100%, 440px); height: auto; margin: 0 auto -24px; }
/* The form side: ember dots along its top edge, clear of the card. */
.login-page .auth-main { position: relative; background: var(--band); border-left: 1px solid var(--line); } /* its own ground, so the two halves separate in dark mode too */
.login-page .auth-main::before {
  content: ''; position: absolute; top: 14px; left: 0; right: 0; height: 48px; pointer-events: none;
  background: var(--dots-accent-anim) 0 0 / 120px 96px, radial-gradient(circle, var(--line-2) 1.6px, transparent 2.2px) 0 0 / 24px 24px;
  -webkit-mask-image: linear-gradient(to left, #000, transparent 60%); mask-image: linear-gradient(to left, #000, transparent 60%);
}
.login-page .auth-main > * { position: relative; }
.auth-main { display: grid; place-items: center; padding: 40px 20px; }
.auth-page { min-height: calc(100vh - 88px); display: grid; place-items: center; padding: 40px 20px; }
.auth-card { width: 100%; max-width: 400px; padding: 2rem; }
.auth-tabs { gap: 0; margin-bottom: 1.5rem; }
.auth-tabs .tab { flex: 1; text-align: center; }

.auth-card .banner { margin: 0 0 1.25rem; }
/* ---------- Billing details ---------- */
.details-page { padding: 48px 20px 88px; display: flex; justify-content: center; }
.details-card { width: 100%; max-width: 680px; padding: 2rem; }
.details-card h1 { font-size: 1.7rem; }
.details-card > .muted { margin: .3rem 0 1.5rem; }
.field-grid { grid-template-columns: 1fr 1fr; column-gap: 1rem; row-gap: 1rem; margin-top: 1.25rem; }
.field-grid .wide { grid-column: 1 / -1; }
/* A tick box with its words beside it. The !important beats `.form label { display: grid }`, which every label in a form gets. */
.check-row { display: flex !important; align-items: flex-start; gap: .6rem; font-weight: 400 !important; font-size: .92rem; cursor: pointer; }
.check-row input[type="checkbox"], .check-row input[type="radio"] { width: 1.1rem; height: 1.1rem; margin: .2rem 0 0; flex: none; }
.check-row a { color: var(--accent-text); }
.details-card > .hint { margin-top: 1.5rem; }
.step.done { display: flex; flex-wrap: wrap; align-items: baseline; gap: .3rem 1rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--bg); padding: .7rem 1rem; }
.step.done strong { color: var(--ok); font-weight: 600; }
.bill-body { margin-top: .5rem; font-size: .88rem; line-height: 1.5; }
@media (max-width: 600px) { .field-grid { grid-template-columns: 1fr; } .details-card { padding: 1.4rem; } }
.pay-card > .muted { margin: .4rem 0 1.4rem; }
.verify-box { margin: 1.25rem 0; }
.verify-box p { margin: .3rem 0 0; color: var(--muted); font-size: .92rem; }
.verify-form { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: .9rem; }
.verify-form input { flex: 1 1 240px; min-width: 0; padding: .5rem .8rem; }
.verify-box .form-status { margin-top: .6rem; }
.pay-card .verify-box { margin: 1.25rem 0 0; }
/* Discord's darker blurple: white text on their usual #5865F2 is only 4.2:1 */
.btn-discord { background: #4752c4; border-color: #4752c4; color: #fff; }
.btn-discord:hover { background: #3c45a5; border-color: #3c45a5; }
.discord-note { margin: .75rem 0 0; }
.or { display: flex; align-items: center; gap: .9rem; margin: 1.4rem 0 1.5rem; color: var(--muted); font-size: .82rem; }
.or::before, .or::after { content: ''; flex: 1; height: 1px; background: var(--line); }


/* Small toggle chips (admin filters, and the status page's component list). */

.chip {
  background: var(--surface); border: 1px solid var(--line-2); border-radius: 999px; padding: .3rem .75rem;
  font: 500 .8rem var(--sans); color: var(--muted); cursor: pointer; transition: all .15s;
}

.chip:hover { color: var(--text); border-color: var(--muted); }

.chip.on { background: var(--accent); border-color: var(--accent); color: var(--accent-fg); }

/* A button that looks like a link (login page, admin). */


.link-btn {
  background: none; border: 0; padding: 0; font: inherit; color: var(--text); text-align: left;
  cursor: pointer; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--line-2);
}

.link-btn:hover { color: var(--accent-text); }

.link-btn .muted { text-decoration: none; display: block; }
/* ---------- 404 ---------- */
.eyebrow-404 { margin: 0 0 .25rem; font: 700 .85rem var(--mono); color: var(--accent-text); letter-spacing: .1em; }
.lost-links { display: grid; gap: .55rem; list-style: none; padding: 0; margin: 1.25rem 0 1.75rem; font-size: .95rem; color: var(--muted); }
.lost-links a { color: var(--text); font-weight: 600; text-underline-offset: 3px; }
.lost-links a:hover { color: var(--accent-text); }


/* One centred card for a page that is a single step: pay, verify, reset, 404. */

.pay-card { width: 100%; max-width: 560px; padding: 2rem; margin: 0 auto; }

@media (max-width: 560px) { .pay-card { padding: 1.4rem; } }

.pay-card h1 { font-size: 1.6rem; }

.pay-card h2 { font-size: 1rem; margin-top: 1.75rem; }

.pay-card a:not(.btn) { color: var(--text); text-underline-offset: 3px; }
/* ---------- Legal pages ---------- */
.legal { max-width: 760px; margin: 0 auto; padding: 64px 24px 96px; }
.legal h1 { font-size: clamp(2rem, 4.5vw, 2.8rem); font-weight: 700; letter-spacing: -.03em; margin-bottom: .3rem; }
.legal .updated { color: var(--muted); font-size: .9rem; margin-bottom: 2rem; }
.legal .summary { border: 1px solid var(--line); background: var(--surface); border-radius: var(--radius-sm); padding: 1rem 1.25rem; margin-bottom: 2rem; }
.legal .summary p { margin: 0; }
.legal .toc { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); padding: 1.1rem 1.5rem; margin-bottom: 2.5rem; }
.legal .toc p { margin: 0 0 .5rem; font-weight: 600; font-size: .9rem; }
.legal .toc ol { columns: 2; column-gap: 2rem; padding-left: 1.2rem; margin: 0; font-size: .92rem; }
.legal .toc a { text-decoration: none; color: var(--muted); }
.legal .toc a:hover { color: var(--accent-text); }
.legal h2 { font-size: 1.3rem; margin: 2.75rem 0 .75rem; padding-top: 1.75rem; border-top: 1px solid var(--line); scroll-margin-top: 80px; }
.legal h3 { font-size: 1.02rem; margin: 1.5rem 0 .4rem; scroll-margin-top: 80px; }
.legal p, .legal li { line-height: 1.75; }
.legal ul, .legal ol { padding-left: 1.4rem; margin: 0 0 1em; }
.legal ul { list-style: disc; }
.legal li { margin-bottom: .4rem; }
.legal a { color: var(--accent-text); text-underline-offset: 3px; }
.legal table { width: 100%; border-collapse: collapse; font-size: .92rem; margin: 0 0 1.25rem; }
.legal th, .legal td { text-align: left; vertical-align: top; padding: .65rem .8rem; border: 1px solid var(--line); }
.legal th { background: var(--surface); font-weight: 600; white-space: nowrap; }
/* Placeholders to replace with your own details before publishing. */
.fill { background: color-mix(in srgb, var(--warn) 28%, transparent); border-bottom: 2px dashed var(--warn); padding: 0 .2rem; border-radius: 2px; }
@media (max-width: 640px) { .legal .toc ol { columns: 1; } .legal th { white-space: normal; } }

/* ---------- Responsive ---------- */
@media (max-width: 1000px) {
  .hero-inner { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .hero-visual { max-width: 560px; }
  .services { grid-template-columns: 1fr; }
  .bento { grid-template-columns: repeat(2, 1fr); }
  .cta-inner { grid-template-columns: 1fr; gap: 2.5rem; }
  .footer-top { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .footer-brand { grid-column: 1 / -1; }
  .auth-split { grid-template-columns: 1fr; }
  .auth-side { display: none; }
}
@media (max-width: 760px) {
  .menu-toggle { display: block; }
  .nav-links {
    position: absolute; top: 88px; left: 0; right: 0; flex-direction: column; align-items: stretch; gap: 0;
    background: var(--bg); border-bottom: 1px solid var(--line); padding: .25rem 24px 1.25rem; display: none;
  }
  .nav-links.open { display: flex; }
  .nav-links a:not(.btn) { padding: .85rem 0; border-bottom: 1px solid var(--line); }
  .nav-links .btn { margin-top: 1rem; }
  .hero { padding: 56px 0 72px; }
  .mock-toast { left: 12px; bottom: -18px; }
  .section, .cta-band { padding: 64px 0; }
  .order-head { flex-direction: column; }
  .cta-band h2 { max-width: none; }
}
@media (max-width: 560px) {
  .bento { grid-template-columns: 1fr; }
  .tile.wide { grid-column: auto; }
  .tile { min-height: 190px; }
  .tabs { gap: 1.25rem; }
  .meter { grid-template-columns: 52px 1fr 92px; gap: .5rem; }
  .form-card { padding: 1.4rem; }
}
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; scroll-behavior: auto !important; }
}
/* Going from one page to another, the new page fades in over the old one instead of cutting to it, in browsers that can
   (the rest load the page as before). Quick, so it never feels like waiting, and not at all for anyone who has asked for
   less motion. */
@media (prefers-reduced-motion: no-preference) { @view-transition { navigation: auto; } }
::view-transition-old(*), ::view-transition-new(*) { animation-duration: .16s; }
/* The header and the cookie notice are on both pages, so they stay where they are while the page changes under them,
   instead of fading out and back in with it. The Portal's menu is a different shape in a different place, so it has a name
   of its own: it holds still between two Portal pages, and fades with the page when coming from or going to a public one. */
header.nav:not(:has([data-account-nav])) { view-transition-name: site-header; }
header.nav:has([data-account-nav]) { view-transition-name: portal-menu; }
.cookie-notice { view-transition-name: cookie-notice; }
/* The next page builds its notice a moment after it is first drawn, so the one already showing stays up until it has. */
::view-transition-old(cookie-notice):only-child { animation: none; }
@media (prefers-reduced-motion: reduce) { ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; } }

/* ---------- Customer reviews ---------- */
.stars { position: relative; display: inline-block; font-size: 1.05rem; line-height: 1; letter-spacing: .12em; color: var(--line-2); white-space: nowrap; vertical-align: middle; }
.stars::before { content: '★★★★★'; }
.stars-fill { position: absolute; top: 0; left: 0; overflow: hidden; white-space: nowrap; color: var(--star); }
.stars-fill::before { content: '★★★★★'; }
.stars-lg { font-size: 1.5rem; }

/* the home page carousel */
.reviews-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 1rem 2rem; max-width: none; }
.reviews-head h2 { margin: 0; }
.reviews-summary { display: flex; align-items: center; gap: .75rem; }
.reviews-score { font: 700 2.4rem var(--sans); letter-spacing: -.03em; line-height: 1; }
.reviews-count { display: block; margin-top: .25rem; font-size: .85rem; color: var(--muted); }
.carousel { position: relative; }
/* The card is as tall as the review being shown: the others are lifted out of the layout while they fade, so only the shown
   one takes up room. Nothing animates the height, which would make the page below it reflow every frame. */
.carousel-slides { position: relative; display: grid; overflow: hidden; }
.slide:not(.active) { position: absolute; top: 0; left: 0; right: 0; }
.slide {
  grid-area: 1 / 1; align-self: start; margin: 0; padding: 2rem 2.25rem; border: 1px solid var(--line); border-radius: var(--radius-lg); background: var(--surface);
  opacity: 0; visibility: hidden; transition: opacity .5s ease, visibility .5s;
}
.slide.active { opacity: 1; visibility: visible; }
.slide-title { margin: .9rem 0 0; font-size: 1.05rem; font-weight: 700; }
.slide-quote { margin: .6rem 0 1.4rem; max-width: 62ch; font-size: clamp(1.05rem, 2vw, 1.3rem); line-height: 1.55; white-space: pre-line; overflow-wrap: anywhere; }
.slide-by { margin: 0; font-size: .92rem; color: var(--muted); }
.slide-by b { color: var(--text); font-weight: 600; }
.slide-verified { display: inline-block; margin-left: .5rem; padding: 0 .45rem; border: 1px solid var(--line-2); border-radius: 4px; font: 500 .68rem var(--mono); color: var(--ok); text-transform: uppercase; letter-spacing: .04em; }
.carousel-controls { display: flex; align-items: center; justify-content: center; gap: 1rem; margin-top: 1.25rem; }
.carousel-controls[hidden] { display: none; }
.carousel-btn { display: grid; place-items: center; width: 38px; height: 38px; border: 1px solid var(--line-2); border-radius: 50%; background: var(--surface); color: var(--text); font-size: 1.15rem; line-height: 1; cursor: pointer; transition: border-color .15s, background .15s, transform .08s ease-out; }
.carousel-btn:hover { border-color: var(--muted); background: var(--raised); }
.carousel-btn:active { transform: scale(.92); }
.carousel-pause { font-size: .6rem; letter-spacing: -.05em; }
.carousel-dots { display: flex; flex-wrap: wrap; justify-content: center; gap: .55rem; }
.carousel-dot { width: 10px; height: 10px; padding: 0; border: 0; border-radius: 50%; background: var(--line-2); cursor: pointer; transition: background .2s, transform .2s; }
.carousel-dot:hover { background: var(--muted); }
.carousel-dot[aria-current="true"] { background: var(--accent); transform: scale(1.25); }
.reviews-cta { margin: 1.5rem 0 0; text-align: center; font-size: .92rem; color: var(--muted); }
.reviews-cta a { color: var(--text); font-weight: 600; text-underline-offset: 3px; }
.reviews-cta a:hover { color: var(--accent-text); }

/* the review form */
.review-page .details-card { max-width: 640px; }
.star-input { margin: 0 0 1.25rem; padding: 0; border: 0; }
.star-input legend { margin-bottom: .5rem; padding: 0; font-size: .86rem; font-weight: 500; }
.star-row { display: inline-flex; flex-direction: row-reverse; gap: .15rem; }
.star-row input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.star-row label { padding: 0 .1rem; font-size: 2.1rem; line-height: 1; color: var(--line-2); cursor: pointer; transition: color .12s, transform .12s; }
.star-row input:checked ~ label, .star-row label:hover, .star-row label:hover ~ label { color: var(--star); }
.star-row label:hover { transform: scale(1.12); }
.star-row input:focus-visible + label { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
.star-word { margin-left: .75rem; font-size: .9rem; color: var(--muted); vertical-align: middle; }
.review-status { --dot: var(--warn); margin: 0 0 1.5rem; padding: .8rem 1rem .8rem 2.15rem; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--raised); font-size: .92rem; }
.review-status.live { --dot: var(--ok); }
.review-status.hidden { --dot: var(--bad); }
.review-status p { margin: 0; }
.char-count { justify-self: end; font: .75rem var(--mono); color: var(--muted); }

/* the admin list */
.review-text { max-width: 60ch; white-space: pre-line; overflow-wrap: anywhere; }

@media (max-width: 640px) {
  .slide { padding: 1.4rem 1.25rem; }
  .reviews-head { align-items: flex-start; }
}

.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.carousel-btn[hidden] { display: none; }

/* ---------- Plans page ---------- */
.plans-page { padding: 40px 0 88px; }
.plans-page .section-head { margin-bottom: 1.5rem; }
/* What comes with every plan: a row of small ticks under the heading. */
.plan-perks { display: flex; flex-wrap: wrap; gap: .5rem .6rem; margin: 0 0 1.75rem; padding: 0; list-style: none; }
.plan-perks li { display: inline-flex; align-items: center; gap: .45rem; padding: .4rem .85rem; border: 1px solid var(--line); border-radius: 999px; background: var(--surface); font: 500 .8rem var(--mono); color: var(--muted); }
.plan-perks li::before { content: '\2713'; color: var(--ok); font-weight: 700; }
/* Which kind of hosting: one card each, with the kind's icon and where its prices start. The open one is lit like the
   Portal's menu, with a lava bar on its left edge. */
/* The kind of service at a glance: a VPS, a game server or a bot. Lives here, not portal.css, because the front page uses it too. */
.svc-ico { display: grid; place-items: center; flex: none; width: 44px; height: 44px; border-radius: 12px; background: color-mix(in srgb, var(--accent) 12%, var(--raised)); color: var(--accent); }
.svc-ico svg { width: 22px; height: 22px; }
.prod-pick { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .75rem; margin: 0 0 1.75rem; }
.prod-tab { position: relative; display: flex; align-items: center; gap: .9rem; padding: .95rem 1.1rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); color: var(--muted); font: 500 .95rem var(--sans); text-align: left; cursor: pointer; overflow: hidden; transition: border-color .15s, background .15s; }
.prod-tab .svc-ico { width: 40px; height: 40px; border-radius: 10px; }
.prod-tab .svc-ico svg { width: 20px; height: 20px; }
.prod-tab > span:last-child { min-width: 0; }
.prod-tab strong { display: block; color: var(--text); font-size: 1rem; }
.prod-tab small { display: block; margin-top: .15rem; font: 400 .78rem var(--mono); color: var(--muted); }
.prod-tab:hover { border-color: var(--line-2); }
.prod-tab.active { border-color: var(--accent); background: color-mix(in srgb, var(--accent) 7%, var(--surface)); }
.prod-tab.soon { opacity: .7; }
.prod-tab.soon .svc-ico { background: var(--raised); color: var(--muted); }
.prod-tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 640px) { .prod-pick { grid-template-columns: 1fr; gap: .5rem; } .prod-tab { padding: .7rem .9rem; } }
/* A fourth product (Image hosting) joins the picker on the Plans page once it has plans. */
.prod-tab[hidden] { display: none; }
.prod-pick.four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1020px) { .prod-pick.four { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .prod-pick.four { grid-template-columns: 1fr; } }
/* "Not sure which plan?": a quiet card with the one button, instead of a line of text. */
.plans-help { display: flex; align-items: center; justify-content: space-between; gap: 1rem 1.5rem; flex-wrap: wrap; margin: 2rem 0 0; padding: 1.1rem 1.35rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); font-size: .95rem; }
.plans-help p { margin: .15rem 0 0; color: var(--muted); font-size: .9rem; }


/* Small print under a field, and a form's result line (login and account pages). */

.field-hint { font-size: .78rem; font-weight: 400; color: var(--muted); line-height: 1.45; }

.pill.ok { color: var(--ok); }

.pill.warn { color: var(--warn); }

.form-status.bad { color: var(--bad); }
/* ---- polish ---- */
/* "Skip to content": invisible until someone tabs to it, so keyboard and screen-reader users can jump past the menu. */
.skip-link { position: absolute; left: 1rem; top: -4rem; z-index: 100; padding: .6rem 1rem; border-radius: var(--radius-sm); background: var(--accent); color: var(--accent-fg); font-weight: 600; text-decoration: none; transition: top .15s; }
.skip-link:focus { top: .75rem; }
/* Show / Hide button inside password boxes. */
.pw-wrap { position: relative; display: block; }
.pw-wrap input { width: 100%; padding-right: 4.6rem; }
/* Centred with `translate`, not `transform`: the press effect further down sets `transform`, which would otherwise undo the
   centring and drop the button out from under the pointer in the middle of a click. */
.pw-toggle { position: absolute; right: .35rem; top: 50%; translate: 0 -50%; padding: .3rem .6rem; border: 0; border-radius: 6px; background: transparent; color: var(--muted); font: 500 .8rem var(--sans); cursor: pointer; }
.pw-toggle:hover { color: var(--text); background: var(--raised); }
.forgot-link { margin: -.35rem 0 .1rem; text-align: right; }


/* ---- front page polish ---- */
/* The menu link for the section being read. */
.nav-links a[aria-current="location"] { color: var(--text); box-shadow: 0 2px 0 var(--accent); padding-bottom: 3px; }
/* Placeholder rows shown while the plans load. */
.plan-skel { height: 340px; border: 1px solid var(--line); border-radius: var(--radius); background: linear-gradient(100deg, transparent 30%, color-mix(in srgb, var(--text) 6%, transparent) 50%, transparent 70%) var(--surface); background-size: 220% 100%; animation: skel 1.4s ease-in-out infinite; }
@keyframes skel { from { background-position: 120% 0; } to { background-position: -120% 0; } }
/* Cards ease in as they scroll into view (see script.js). */
.reveal { opacity: 0; }
.reveal.in { opacity: 1; animation: reveal-in .5s ease backwards; animation-delay: var(--d, 0ms); }
@keyframes reveal-in { from { opacity: 0; transform: translateY(14px); } }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; }
  .reveal.in { animation: none; }
  .plan-skel { animation: none; }
}
@media print { .reveal { opacity: 1; } }
.contact-links a[hidden] { display: none; }
.tile p a { color: var(--text); text-underline-offset: 3px; }

/* ---------- Public status page ---------- */
/* One colour per state, shared by pills, chips, the banner, incident edges and the day bars. Every use also has an icon and a word. */
.st-operational, .st-bar-operational, .st-edge-operational { --st: var(--ok); }
.st-degraded, .st-bar-degraded, .st-edge-degraded { --st: var(--warn); }
.st-partial_outage, .st-bar-partial_outage, .st-edge-partial_outage { --st: var(--serious); }
.st-major_outage, .st-bar-major_outage, .st-edge-major_outage { --st: var(--bad); }
.st-maintenance, .st-bar-maintenance, .st-edge-maintenance { --st: var(--info); }
.st-nodata, .st-bar-nodata { --st: var(--line-2); }

/* The page is built like the front page: an Ink hero (the headline and the one-line answer on the left, a live panel of
   every service on the right), then full-width sections under the same headings. */
.st-hero { padding: 64px 0 100px; }
.st-hero .lead { margin-bottom: 1.5rem; }
/* While status.js is fetching, the three places it fills keep the room they will need, so the page does not jump (and the
   footer does not flash past) when the answer arrives. */
#status-overall:empty { min-height: 105px; }
#status-panel:empty { min-height: 320px; }
.st-loading { min-height: 100vh; }
.st-overall { display: flex; align-items: center; gap: 1rem; max-width: 36rem; padding: 1rem 1.25rem; background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius); }
.st-overall h2 { margin: 0 0 .1rem; font-size: 1.3rem; }
.st-overall p { margin: 0; }
.st-overall-icon { flex: none; display: grid; place-items: center; width: 2.6rem; height: 2.6rem; border-radius: 50%; background: var(--st); color: var(--surface); font: 700 1.25rem var(--mono); }
.st-panel-rows { list-style: none; margin: 0; padding: 0; }
.st-panel-rows li { display: flex; justify-content: space-between; align-items: center; gap: .5rem 1rem; flex-wrap: wrap; padding: .85rem 0; font-weight: 600; }
.st-panel-rows li:first-child { padding-top: 0; }
.st-panel-rows li + li { border-top: 1px solid var(--line); }
.st-panel-foot { display: flex; justify-content: space-between; gap: .5rem 1rem; flex-wrap: wrap; margin: 0; padding-top: .9rem; border-top: 1px solid var(--line); font: .75rem var(--mono); color: var(--muted); }

.st-sec { padding: 64px 0; }
.st-sec + .st-sec:not(.alt) { padding-top: 0; }
.st-sec .section-head { margin-bottom: 1.75rem; }
.st-sec .plans-help { margin-top: 2.5rem; }
.st-none { margin: 0; padding: 1.5rem; border: 1px dashed var(--line-2); border-radius: var(--radius); color: var(--muted); }

.st-pill { display: inline-flex; align-items: center; gap: .45rem; padding: .22rem .7rem .22rem .3rem; border: 1px solid color-mix(in srgb, var(--st) 55%, var(--line)); border-radius: 999px; background: color-mix(in srgb, var(--st) 12%, transparent); font: 500 .78rem var(--mono); white-space: nowrap; }
.st-icon { display: grid; place-items: center; width: 1.15rem; height: 1.15rem; border-radius: 50%; background: var(--st); color: var(--surface); font: 700 .72rem var(--mono); line-height: 1; } /* the card colour on a status colour: readable in both themes */
.st-chip { display: inline-block; margin: 0 .35rem .25rem 0; padding: .1rem .55rem; border: 1px solid color-mix(in srgb, var(--st) 55%, var(--line)); border-radius: 999px; background: color-mix(in srgb, var(--st) 12%, transparent); font: 500 .76rem var(--mono); }
.st-affects { margin: .5rem 0 0; }

/* the components */
/* One card per service, two across, each with a bar along its top in the colour of its state (like the "What we host" cards). */
.st-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; list-style: none; margin: 0; padding: 0; }
.st-row { position: relative; padding: 1.5rem 1.5rem 1.25rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
.st-row::before { content: ''; position: absolute; top: -1px; left: 1.5rem; right: 1.5rem; height: 3px; border-radius: 0 0 3px 3px; background: var(--st); }
@media (max-width: 900px) { .st-grid { grid-template-columns: minmax(0, 1fr); } }
.st-row-top { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; }
.st-row-top h3 { margin: 0 0 .1rem; font-size: 1.02rem; }
.st-bars { display: flex; gap: 2px; height: 34px; margin: .9rem 0 .4rem; }
.st-bar { flex: 1 1 0; min-width: 2px; border-radius: 2px; background: var(--st, var(--line)); transition: transform .12s; }
.st-bars .st-bar:hover { transform: scaleY(1.12); }
.st-bar.st-bar-nodata { background: var(--line); }
.st-row-foot { display: flex; justify-content: space-between; gap: 1rem; font: 400 .76rem var(--mono); }
.st-uptime { color: var(--text); }
.st-legend { display: flex; flex-wrap: wrap; gap: .5rem 1.1rem; margin: .9rem 0 0; font-size: .8rem; }
.st-legend span { display: inline-flex; align-items: center; gap: .4rem; }
.st-legend .st-bar { flex: none; display: inline-block; width: 10px; height: 10px; }
.st-tip { position: fixed; z-index: 60; padding: .35rem .6rem; background: var(--raised); border: 1px solid var(--line-2); border-radius: var(--radius-sm); box-shadow: var(--shadow); font: 400 .78rem var(--mono); white-space: nowrap; pointer-events: none; }
.st-tip[hidden] { display: none; }

/* incidents and maintenance */
.st-incident { margin-bottom: 1rem; padding: 1.35rem 1.5rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); }
.st-incident header { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; }
.st-incident h3 { margin: 0; font-size: 1.05rem; }
/* The worst it got for anything it affects, as a dot before its title. */
.st-incident h3::before { content: ''; display: inline-block; width: 8px; height: 8px; margin-right: .6rem; border-radius: 50%; background: var(--st, var(--line-2)); vertical-align: .08em; }
.st-step { padding: .12rem .6rem; border: 1px solid var(--line-2); border-radius: 999px; font: 500 .74rem var(--mono); text-transform: uppercase; letter-spacing: .04em; white-space: nowrap; }
.st-window { margin: .4rem 0 0; font: 500 .85rem var(--mono); }
.st-updates { list-style: none; margin: .9rem 0 0 .35rem; padding: 0 0 0 1rem; border-left: 2px solid var(--line); }
.st-updates li + li { margin-top: .9rem; }
.st-update-head { display: flex; align-items: baseline; gap: .75rem; flex-wrap: wrap; }
.st-update-head time { color: var(--muted); font: 400 .76rem var(--mono); }
.st-update-body p { margin: .2rem 0 0; }
.st-day { margin-top: 1rem; }
.st-day h3 { margin: 0 0 .5rem; }
.st-past { margin-bottom: .5rem; padding: .9rem 1.25rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-btn); }
.st-past summary { display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap; cursor: pointer; }
.st-past-title { font-weight: 600; }
.st-past[open] summary { margin-bottom: .4rem; }
.st-stale { margin: 1rem 0 0; max-width: 36rem; }

@media (max-width: 560px) {
  .st-hero { padding: 48px 0 80px; }
  .st-sec { padding: 48px 0; }
  .st-bars { gap: 1px; height: 28px; }
  .st-row { padding: 1.25rem 1rem 1rem; }
  .st-row::before { left: 1rem; right: 1rem; }
}


.st-step-investigating, .st-step-identified, .st-step-monitoring { border-color: var(--warn); }
.st-step-resolved { border-color: var(--ok); }
.st-step-scheduled { border-color: var(--info); }
.st-dot { display: inline-block; width: .55rem; height: .55rem; margin-right: .5rem; border-radius: 50%; background: var(--st, var(--line-2)); vertical-align: middle; }
/* ---------- Login and sign-up screen ---------- */
.login-page .auth-main { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1.1rem; }
.login-page .auth-card { max-width: 430px; padding: 2.25rem 2.25rem 1.75rem; box-shadow: var(--shadow); }
.auth-head { margin: 0 0 1.5rem; }
.auth-head h1 { margin: 0 0 .3rem; font-size: 1.75rem; letter-spacing: -.03em; }
.auth-next { margin: 0 0 1.25rem; padding: .7rem .9rem; border: 1px solid color-mix(in srgb, var(--accent) 45%, var(--line)); border-radius: var(--radius-sm); background: color-mix(in srgb, var(--accent) 8%, var(--surface)); font-size: .9rem; }
.auth-next[hidden] { display: none; }

/* the two tabs as a segmented control */
.login-page .auth-tabs { gap: .25rem; margin: 0 0 1.5rem; padding: .25rem; border: 1px solid var(--line); border-radius: 10px; background: var(--raised); }
.login-page .auth-tabs .tab { margin: 0; padding: .55rem .5rem; border: 0; border-radius: 7px; font-weight: 600; }
.login-page .auth-tabs .tab.active { background: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(0, 0, 0, .35); }
.login-page .auth-tabs .tab:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* messages beside the field they are about */
.field-error { min-height: 0; color: var(--bad); font-size: .8rem; font-weight: 500; }
.field-error:empty { display: none; }
.field-warn { color: var(--warn); font-size: .8rem; font-weight: 500; }
.field-warn[hidden] { display: none; }
.login-page .form input { padding: .75rem .9rem; }
.login-page .form-status { margin-top: 1rem; min-height: 0; }
.login-page .form-status:empty { display: none; }
.login-page .form-status a, .login-page .form-status .link-btn { color: var(--text); font-weight: 600; text-underline-offset: 3px; }
.login-page .btn-lg { padding-top: .8rem; padding-bottom: .8rem; }

/* the password checklist */
.pw-rules { display: grid; gap: .3rem; margin: -.35rem 0 .1rem; font-size: .82rem; color: var(--muted); }
.pw-rules li { display: flex; align-items: center; gap: .55rem; }
.pw-rules li::before { content: ''; flex: none; width: .95rem; height: .95rem; border: 1.5px solid var(--line-2); border-radius: 50%; }
.pw-rules li.ok { color: var(--text); }
.pw-rules li.ok::before { border-color: var(--ok); background: var(--ok) center / 70% no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.4 5 8.8 9.6 3.4' fill='none' stroke='%230d0d0f' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }

.auth-assure { max-width: 430px; margin: 0; color: var(--muted); font-size: .8rem; text-align: center; }

/* the orange side panel */

@media (max-width: 720px) {
  .login-page .auth-main { justify-content: flex-start; padding-top: 28px; }
  .login-page .auth-card { padding: 1.75rem 1.4rem 1.4rem; }
}

/* ---------- Two-factor login ---------- */
.tf-page .box { max-width: 720px; }
.tf-box + .tf-box { margin-top: 1.5rem; }
.tf-box .box-body { display: grid; gap: 1rem; }
.tf-points { display: grid; gap: .4rem; margin: 0; padding-left: 1.2rem; list-style: disc; color: var(--muted); font-size: .92rem; }
.tf-scan { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 1.75rem; align-items: start; }
.tf-qr-wrap { padding: .6rem; background: #fff; border: 1px solid var(--line-2); border-radius: var(--radius); line-height: 0; }
.tf-qr { width: 220px; height: 220px; image-rendering: pixelated; }
.tf-manual { display: grid; gap: .6rem; justify-items: start; }
.tf-manual p { margin: 0; }
.tf-key { display: inline-block; padding: .55rem .8rem; background: var(--raised); border: 1px solid var(--line-2); border-radius: var(--radius-sm); font: 500 1rem var(--mono); letter-spacing: .06em; overflow-wrap: anywhere; }
.tf-code { font: 500 1.4rem var(--mono) !important; letter-spacing: .28em; text-align: center; }
.tf-code::placeholder { letter-spacing: .1em; font-size: 1rem; }
.tf-form { max-width: 26rem; }
.tf-codes { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .5rem .9rem; margin: 0; padding: 1rem; list-style: none; background: var(--raised); border: 1px solid var(--line-2); border-radius: var(--radius); }
.tf-codes code { font: 500 1.05rem var(--mono); letter-spacing: .08em; user-select: all; }
.tf-panel { margin-top: 1rem; padding: 1.1rem 1.25rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg); }
.tf-panel[hidden] { display: none; }
.tf-panel h3 { margin: 0 0 .8rem; font-size: 1rem; }
.tf-alt { margin: .25rem 0 0; text-align: center; }
@media (max-width: 640px) { .tf-scan { grid-template-columns: 1fr; justify-items: center; } .tf-manual { justify-items: stretch; } }
/* Printing the recovery codes prints ONLY the codes: the button sets this class for the moment of printing. (It must never apply on its own, or every other page would print blank.) */
@media print { body.printing-codes * { visibility: hidden; } body.printing-codes .tf-codes, body.printing-codes .tf-codes * { visibility: visible; } body.printing-codes .tf-codes { position: absolute; left: 0; top: 0; border: 0; } }
.login-page .auth-tabs[hidden], .login-page #discord-box[hidden] { display: none; }

/* ===========================================================================
   The shared pieces (see the "ui kit" section of common.js). One dialog, one
   toast, one empty state, one loading shape, used by every page.
   =========================================================================== */

/* ---- asking before something irreversible ---- */
/* The browser's own <dialog>, opened as a modal (see modal() in common.js). */
.dialog::backdrop { background: rgba(0, 0, 0, .55); backdrop-filter: blur(2px); animation: dialog-in .14s ease-out; }
.dialog { width: calc(100% - 2.5rem); max-width: 30rem; padding: 0; color: inherit; background: var(--surface); border: 1px solid var(--line-2); border-radius: var(--radius); box-shadow: var(--shadow); animation: dialog-rise .16s ease-out; }
.dialog-body { padding: 1.4rem 1.5rem .25rem; }
.dialog-body h2 { margin: 0 0 .6rem; font-size: 1.15rem; }
.dialog-body p { margin: 0 0 .8rem; font-size: .95rem; line-height: 1.6; }
.dialog-note { color: var(--muted); font-size: .88rem !important; }
.dialog-actions { display: flex; justify-content: flex-end; gap: .6rem; flex-wrap: wrap; padding: 1rem 1.5rem 1.35rem; }
@keyframes dialog-in { from { opacity: 0; } }
@keyframes dialog-rise { from { opacity: 0; transform: translateY(8px) scale(.98); } }
@media (prefers-reduced-motion: reduce) { .dialog::backdrop, .dialog { animation: none; } }

/* ---- a short message that something worked ---- */
.toasts { position: fixed; z-index: 320; left: 50%; bottom: 1.5rem; transform: translateX(-50%); display: grid; gap: .5rem; width: min(26rem, calc(100vw - 2rem)); pointer-events: none; }

/* ---- the cookie notice: informational, not a consent choice (see privacy.html#cookies) ---- */
.cookie-notice {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 250; display: flex; align-items: center; justify-content: center;
  gap: .5rem 1.25rem; flex-wrap: wrap; padding: .9rem 1.25rem; background: var(--raised); border-top: 1px solid var(--line);
  box-shadow: var(--shadow); font-size: .88rem;
}
.cookie-notice p { margin: 0; color: var(--muted); max-width: 60ch; }
.cookie-notice a { color: var(--text); text-underline-offset: 3px; }
.toast { --dot: var(--ok); pointer-events: auto; padding: .8rem 1.1rem .8rem 2.15rem; border: 1px solid var(--line-2); border-radius: var(--radius); background: var(--raised); color: var(--text); font-size: .92rem; box-shadow: var(--shadow); cursor: pointer; animation: toast-in .18s ease-out; }
.toast-bad { --dot: var(--bad); }
.toast.going { opacity: 0; transform: translateY(6px); transition: opacity .2s, transform .2s; }
@keyframes toast-in { from { opacity: 0; transform: translateY(10px); } }
@media (prefers-reduced-motion: reduce) { .toast { animation: none; } }

/* ---- while a list loads ---- */
.loading-block { padding: .35rem 0; }
.skeleton { display: grid; gap: .7rem; }
.sk-line { display: block; height: 1rem; border-radius: 6px; background: linear-gradient(90deg, var(--raised) 25%, color-mix(in srgb, var(--line-2) 55%, var(--raised)) 50%, var(--raised) 75%); background-size: 240% 100%; animation: sk 1.3s ease-in-out infinite; }
.sk-line:nth-child(2) { width: 82%; }
.sk-line:nth-child(3) { width: 64%; }
@keyframes sk { from { background-position: 140% 0; } to { background-position: -40% 0; } }
@media (prefers-reduced-motion: reduce) { .sk-line { animation: none; } }

/* ---- an empty list ---- */
.empty-state { padding: 2.75rem 1.5rem; text-align: center; border: 1px dashed var(--line-2); border-radius: var(--radius); background: color-mix(in srgb, var(--surface) 60%, transparent); }
.empty-state h2 { margin: 0 0 .4rem; font-size: 1.1rem; }
.empty-state p { margin: 0 auto; max-width: 48ch; }
.empty-icon { margin-bottom: .75rem; font-size: 1.9rem; line-height: 1; filter: grayscale(1); opacity: .45; }
.empty-action { margin-top: 1.25rem !important; }

/* ---- copying a value ---- */
.copy-btn.copied { border-color: var(--ok); color: var(--ok); }
.copy-row { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.copy-row code { flex: 1 1 12rem; min-width: 0; padding: .55rem .75rem; background: var(--field); border: 1px solid var(--line-2); border-radius: var(--radius-sm); font: 500 .92rem var(--mono); overflow-wrap: anywhere; }

/* ---- when something happened ---- */
.when { color: inherit; text-decoration: none; border-bottom: 1px dotted transparent; cursor: help; }
.when:hover { border-bottom-color: var(--line-2); }

/* ---- a light press-down on the small icon buttons, so tapping them feels responsive ---- */
.pw-toggle, .announce-close, .chat-chip-x, .copy-btn { transition: transform .08s ease-out; }
.pw-toggle:active, .announce-close:active, .chat-chip-x:active, .copy-btn:active { transform: scale(.88); }
@media (prefers-reduced-motion: reduce) {
  .nav-links a:not(.btn), .menu-toggle, .carousel-btn, .theme-opt, .seg-card, .pw-toggle, .announce-close, .chat-chip-x, .copy-btn { transition: none; }
  .nav-links a:not(.btn):active, .menu-toggle:active, .carousel-btn:active, .theme-opt:active, .seg-card:active,
  .pw-toggle:active, .announce-close:active, .chat-chip-x:active, .copy-btn:active { transform: none; }
}

/* ---- the appearance switch ---- */
.theme-switch { display: inline-flex; padding: .2rem; border: 1px solid var(--line); border-radius: 999px; background: var(--raised); }
.theme-opt { padding: .35rem .85rem; border: 0; border-radius: 999px; background: none; color: var(--muted); font: 500 .85rem var(--sans); cursor: pointer; transition: background .15s, color .15s, transform .08s ease-out; }
.theme-opt:hover { color: var(--text); }
.theme-opt:active { transform: scale(.92); }
.theme-opt.on { background: var(--surface); color: var(--text); box-shadow: 0 1px 3px rgba(0, 0, 0, .3); }
.theme-opt:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* ---- a dialog that asks for something typed ---- */
.dialog-field { display: grid; gap: .4rem; margin: 0 0 .9rem; font-size: .88rem; font-weight: 500; }
.dialog-field input, .dialog-field textarea, .dialog-field select { width: 100%; }
/* Short fields side by side (a node's capacity), one under another where there is no room. */
.dialog-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr)); column-gap: .75rem; align-items: start; }
.dialog-form .check-row { margin: 0; }

/* The "Loading…" written into the HTML: visible without JavaScript, replaced by the skeleton the moment a script runs. */
.loading-note { color: var(--muted); }

.footer-theme { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.footer-theme-label { font-size: .85rem; color: var(--muted); }

/* Portal pages: the same brand textures as the front page, kept clear of text. A soft lava glow in the top-right corner of
   the page, and a strip of ember dots along the top of the content, inside extra top padding so it never sits behind a
   heading. Every Portal page has the account menu, so this needs nothing on the pages themselves. */
body:has(.nav [data-account-nav]) { background: radial-gradient(900px 520px at 100% 0, color-mix(in srgb, var(--accent) 8%, transparent), transparent 70%) no-repeat, radial-gradient(760px 440px at 100% 100%, color-mix(in srgb, var(--accent) 7%, transparent), transparent 70%) no-repeat fixed, var(--bg); }
body:has(.nav [data-account-nav]) main { position: relative; padding-top: 76px; }
/* Textures on every Portal page (BRAND.md: Patterns and graphics): ember dots over the top-right and bottom-left corners of the
   window, fading to nothing towards the middle, and the rack stripes along its foot. Both sit behind the content. */
body:has(.nav [data-account-nav])::before, .bg-dots::before, .bg-field::before, .bg-field-end::after {
  content: ''; position: absolute; inset: -96px 0 0 -120px; z-index: -1; pointer-events: none; animation: dots-drift 80s ease-in-out infinite alternate;
  background: var(--dots-accent) 0 0 / 120px 96px, radial-gradient(circle, var(--line-2) 1.6px, transparent 2.2px) 0 0 / 24px 24px;
  -webkit-mask-image: radial-gradient(70% 60% at 100% 0%, #000 15%, transparent 72%), radial-gradient(42% 60% at 0% 100%, #000 15%, transparent 72%);
  mask-image: radial-gradient(70% 60% at 100% 0%, #000 15%, transparent 72%), radial-gradient(42% 60% at 0% 100%, #000 15%, transparent 72%);
  -webkit-mask-composite: source-over; mask-composite: add;
}
body:has(.nav [data-account-nav])::after, .bg-dots::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 64px; z-index: -1; pointer-events: none;
  background: var(--rack) left bottom repeat-x;
  -webkit-mask-image: linear-gradient(to left, #000 15%, transparent 55%); mask-image: linear-gradient(to left, #000 15%, transparent 55%);
}
/* On a Portal page they are fixed to the window, so they cover the whole area beside the menu and stay put as it scrolls. */
body:has(.nav [data-account-nav]) { isolation: isolate; } /* so the textures below sit above the body's own background */
body:has(.nav [data-account-nav])::before, body:has(.nav [data-account-nav])::after { position: fixed; }
@keyframes dots-drift { to { transform: translate(120px, 96px); } }
/* With "reduce motion" on: no drift, and the still versions of the blinking patterns. */
@media (prefers-reduced-motion: reduce) {
  :root, :root[data-theme="dark"], :root[data-theme="light"] { --rack: var(--rack-still); --rack-ink: var(--rack-ink-still); --dots-accent-anim: var(--dots-accent); }
  body:has(.nav [data-account-nav])::before, .bg-dots::before, .bg-field::before, .bg-field-end::after { animation: none; }
}
/* the same textures on a public page (the plans and status pages) */
.bg-dots { position: relative; isolation: isolate; overflow: hidden; }
/* The drifting dot field alone, for a front-page section: on whichever pseudo-element its edge pattern leaves free. */
.bg-field, .bg-field-end { isolation: isolate; overflow: hidden; }
/* a section with rack stripes along its top (Included) keeps its dots to the bottom corners, so the two never overlap */
.bg-field-end::after { -webkit-mask-image: radial-gradient(42% 60% at 0% 100%, #000 15%, transparent 72%), radial-gradient(42% 60% at 100% 100%, #000 15%, transparent 72%); mask-image: radial-gradient(42% 60% at 0% 100%, #000 15%, transparent 72%), radial-gradient(42% 60% at 100% 100%, #000 15%, transparent 72%); }
/* A Portal visitor already has the window-wide textures, so a page's own copy would double them. */
body:has(.nav [data-account-nav]) .bg-dots::before, body:has(.nav [data-account-nav]) .bg-dots::after { display: none; }
@media print { body:has(.nav [data-account-nav]) { background: none; } body:has(.nav [data-account-nav])::before, body:has(.nav [data-account-nav])::after { display: none; } }
@media print { body { padding-left: 0 !important; } }
