/* ─────────────────────────────────────────────────────────────
   CometFare Dark Pages — shared design system for the info pages
   (releases, blog, support, voyager, discover).

   This REPLACES cometfare-sky-pages.css + cometfare-sky-footer.css
   (2026-07-28 rebuild). The sky-blue/white system is gone; the info
   pages now speak the landing page's language:

   - dark mode: the page is black, every card is a black slab
   - COLD (#6cbcff blue) × WARM (#c9b3ff beige): type and edges are
     beige at rest and turn blue the moment a control is engaged —
     the same one rule the sky header and the hero download CTA run
   - the landing page's green is deliberately ABSENT here: green
     belongs to index.html only
   - no top hero image: each page opens with a left-aligned title
     block (.dark-page-head)
   - the page's liquid decoration is a SEPARATOR, not a border: a
     .goo-sep strip straddling the seam between content and footer
     (cometfare-goo.js in band mode). releases.html is the one page
     that still wears the full liquid border (cometfare-goo-frame.js)
   - compact: paddings are tight on purpose so a page fits in one
     screen and the first scroll lands on the footer

   Like its sky predecessor it restyles the same cf-* component
   classes the page scripts generate, so the functional JS keeps
   working untouched. Load with cometfare-sky-header.css; the footer
   comes from cometfare-footer.js (the black site-wide footer).
   ───────────────────────────────────────────────────────────── */

:root {
    color-scheme: dark;
    /* the cold × warm pair — same values as the hero download CTA */
    --cf-cold: #6cbcff;
    --cf-cold-deep: #1d5488;
    --cf-warm: #c9b3ff;
    --cf-warm-soft: rgba(201, 179, 255, 0.72);
    --cf-warm-faint: rgba(201, 179, 255, 0.45);
    --cf-surface: #000000;
    --cf-edge: rgba(201, 179, 255, 0.22);          /* resting card border */
    --cf-edge-active: rgba(108, 188, 255, 0.5);    /* engaged border */
    --cf-text: rgba(255, 255, 255, 0.88);
    --cf-text-soft: rgba(255, 255, 255, 0.62);
    --card-shadow: 0 18px 44px rgba(0, 0, 0, 0.5);

    /* legacy names some inline styles/scripts still reference */
    --ink: #ffffff;
    --soft-ink: rgba(255, 255, 255, 0.62);
    --sky: var(--cf-cold);
    --sky-deep: var(--cf-cold);
    --sky-hover: #8ecbff;
    --cf-card-bg: #0a0d12;
    --cf-line: rgba(201, 179, 255, 0.22);
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
    position: relative;
    margin: 0;
    min-width: 320px;
    font-family: "Quicksand", "Nunito", system-ui, sans-serif;
    background: #000000;
    color: var(--cf-text);
    overflow-x: hidden;
    /* the page is one column: the framed box, then the footer under it */
    display: flex;
    flex-direction: column;
}

/* ── THE FOLD RULE ──
   The framed box is ALWAYS at least one full screen tall, so the footer
   begins exactly at the fold and is never partly visible on a page whose
   content came up short.

   ⚠️ The floor belongs HERE, on the frame — not on <body>. A body-level
   `min-height: 100dvh` looks like it does the same job but doesn't: body
   is the frame PLUS the footer, so filling the viewport with both leaves
   the frame only (100dvh − footer height) and the footer's top edge sits
   inside the first screen. That is exactly the peeking bug this replaces.

   ⚠️ 100vh, deliberately NOT 100dvh. On mobile `vh` resolves to the LARGE
   viewport (chrome retracted), which is the only value that still clears
   the fold once the URL bar scrolls away; dvh shrinks with the chrome and
   would let the footer creep back into view, and it re-lays-out mid-scroll
   while doing it. Over-reserving when the chrome is showing is the
   harmless direction.

   Two class names, one behaviour: releases.html keeps `.goo-frame`
   (it is still a painted frame); blog/discover/support/voyager use
   `.page-column`, which is the same layout column with no fluid on it. */
.goo-frame,
.page-column {
    flex: 1 0 auto;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
}

/* <main> eats the slack, so the frame's bottom edge lands at the fold
   rather than hugging short content halfway up the screen */
.goo-frame > main,
.page-column > main { flex: 1 0 auto; }

.cf-footer { flex: 0 0 auto; }

/* ── THE LIQUID FRAME ──
   .goo-frame is the positioned host cometfare-goo-frame.js paints in.
   It spans from the very top of the page to the bottom of <main>, so
   the fluid borders the top, both sides, and the content's floor. The
   canvas never catches the pointer and sits under the content. */
.goo-frame { position: relative; isolation: isolate; }

/* ⚠️ The canvas MUST be excluded from the .goo-frame > * rule below.
   Both selectors are specificity (0,1,0), so the later one wins — and
   `position: relative` on the canvas drops it back INTO the flow: it
   becomes a page-tall block at the top that shoves every bit of content
   down by its own height, and its in-flow height then re-triggers the
   ResizeObserver in a loop. Hence :not() here rather than reordering. */
.goo-frame > .goo-frame__canvas {
    position: absolute;
    inset: 0;
    z-index: 0;
    display: block;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

.goo-frame > *:not(.goo-frame__canvas) { position: relative; z-index: 1; }

/* ── THE GOO SEPARATOR ──
   What replaced the frame on blog/discover/support/voyager. Same band
   engine index.html runs between its colour areas (cometfare-goo.js,
   band mode: a two-edged body of fluid with the area above showing
   through one edge and uBase painted past the other), but wearing the
   frame's periwinkle palette instead of index's greens.

   ⚠️ The strip costs ZERO layout height, on purpose. Index gives its
   bands a real slab of page to sit in; here the separator has to sit ON
   the seam between the content and the footer, overlapping into both.
   So the negative margins are exactly half the height each: the box
   consumes its own height back, the footer still begins precisely where
   <main> ended, and the fluid bleeds symmetrically into the black above
   and the black below. Change `height` and both margins together or the
   footer starts drifting up or down the page.

   z-index because the footer is appended AFTER this element and would
   otherwise paint over the half of the goo that reaches into it.
   pointer-events: none because the strip physically covers the top of
   the footer and the bottom of the content — without it the first row
   of footer links stops being clickable. */
.goo-sep {
    --goo-sep-h: clamp(84px, 8.5vw, 132px);
    position: relative;
    z-index: 2;
    flex: 0 0 auto;
    width: 100%;
    height: var(--goo-sep-h);
    margin-top: calc(var(--goo-sep-h) / -2);
    margin-bottom: calc(var(--goo-sep-h) / -2);
    overflow: hidden;
    pointer-events: none;
    /* no WebGL / reduced motion: nothing to see. Both sides are black,
       so an unpainted strip is invisible rather than a wrong-colour gap. */
    background: none;
}

.goo-sep > canvas {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

a { color: inherit; }
img { display: block; max-width: 100%; }

/* ── PAGE HEAD: left-aligned title, no hero, no image ──
   Clears the fixed sky nav, then gets straight to the point. */
.dark-page-head {
    width: min(1180px, calc(100% - clamp(64px, 8vw, 110px)));
    margin: 0 auto;
    padding: clamp(96px, 14vh, 128px) 0 clamp(14px, 2vh, 22px);
    text-align: left;
}

.dark-page-head h1,
.cf-title {
    margin: 0;
    font-family: "Fredoka", "Quicksand", sans-serif;
    font-size: clamp(2rem, 4.6vw, 3.2rem);
    font-weight: 600;
    line-height: 1.04;
    letter-spacing: -0.01em;
    color: var(--cf-warm);
}

.dark-page-head p,
.cf-lead {
    margin: 10px 0 0;
    max-width: 62ch;
    font-size: clamp(0.92rem, 1.3vw, 1rem);
    font-weight: 600;
    line-height: 1.55;
    color: var(--cf-text-soft);
}

/* ── PAGE SHELL — compact on purpose ── */
.cf-page-shell,
.sky-shell,
.dark-shell {
    width: min(1180px, calc(100% - clamp(64px, 8vw, 110px)));
    margin: 0 auto;
    padding: clamp(10px, 1.6vh, 18px) 0 clamp(30px, 4vh, 48px);
}

.cf-page-shell > * + * { margin-top: clamp(12px, 1.8vw, 18px); }

/* section headings inside page bodies */
.sky-section-title {
    font-family: "Fredoka", "Quicksand", sans-serif;
    font-size: clamp(1.3rem, 2vw, 1.7rem);
    font-weight: 600;
    line-height: 1.2;
    margin: 0;
    color: var(--cf-warm);
}

/* ── BUTTONS: black slab, beige at rest, blue when engaged ── */
.cf-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    font: inherit;
    font-weight: 800;
    font-size: 0.9rem;
    padding: 10px 18px;
    border-radius: 14px;
    cursor: pointer;
    text-decoration: none;
    border: 1px solid var(--cf-edge);
    background: var(--cf-surface);
    color: var(--cf-warm);
    transition: color 0.16s ease, border-color 0.16s ease, box-shadow 0.16s ease;
}

.cf-btn:hover,
.cf-btn:focus-visible {
    color: var(--cf-cold);
    border-color: var(--cf-edge-active);
}

.cf-btn.is-primary {
    border-color: rgba(201, 179, 255, 0.4);
    box-shadow: 0 10px 26px rgba(0, 0, 0, 0.45);
}

.cf-btn.is-primary:hover,
.cf-btn.is-primary:focus-visible {
    border-color: var(--cf-cold);
    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.55);
}

.cf-btn.is-quiet {
    border-color: transparent;
    background: rgba(201, 179, 255, 0.08);
    color: var(--cf-warm-soft);
}

.cf-btn.is-quiet:hover {
    background: rgba(108, 188, 255, 0.12);
    color: var(--cf-cold);
    border-color: transparent;
}

.cf-btn:disabled { opacity: 0.5; cursor: not-allowed; }

/* ── CHIPS (filters, tag picker, reply actions) ── */
.cf-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font: inherit;
    font-size: 0.8rem;
    font-weight: 700;
    padding: 6px 13px;
    border-radius: 999px;
    border: 1px solid transparent;
    background: rgba(201, 179, 255, 0.09);
    color: var(--cf-warm-soft);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.cf-chip:hover {
    background: rgba(108, 188, 255, 0.12);
    color: var(--cf-cold);
}

.cf-chip.is-active {
    background: rgba(108, 188, 255, 0.16);
    border-color: var(--cf-cold);
    color: var(--cf-cold);
}

.cf-vote-chip.is-up.is-active { background: rgba(34, 197, 94, 0.2); border-color: #22c55e; color: #4ade80; }
.cf-vote-chip.is-down.is-active { background: rgba(239, 68, 68, 0.16); border-color: #ef4444; color: #f87171; }

/* ── FIELDS ── */
.cf-field,
.cf-select,
.cf-textarea,
.cf-search {
    width: 100%;
    font: inherit;
    font-weight: 600;
    font-size: 0.92rem;
    color: var(--cf-text);
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid var(--cf-edge);
    border-radius: 13px;
    padding: 11px 15px;
    outline: none;
    transition: border-color 0.15s ease;
}

.cf-field:focus,
.cf-select:focus,
.cf-textarea:focus,
.cf-search:focus { border-color: var(--cf-cold); }

.cf-field::placeholder,
.cf-textarea::placeholder,
.cf-search::placeholder { color: rgba(201, 179, 255, 0.35); font-weight: 600; }

.cf-textarea { min-height: 96px; resize: vertical; }

.cf-select { cursor: pointer; }
.cf-select option { background: #0a0d12; color: var(--cf-text); }

.cf-search { max-width: 300px; }

.cf-field-group { display: grid; gap: 7px; }

.cf-field-label {
    font-size: 0.84rem;
    font-weight: 800;
    color: var(--cf-warm);
}

.cf-field-hint {
    font-weight: 600;
    color: var(--cf-text-soft);
    font-size: 0.78rem;
}

/* ── FORM CARD: the black slab with the resting warm edge ── */
.cf-form-card {
    background: var(--cf-surface);
    border: 1px solid var(--cf-edge);
    border-radius: 20px;
    box-shadow: var(--card-shadow);
    padding: clamp(16px, 2.4vw, 26px);
    display: grid;
    gap: 12px;
}

.cf-form-card strong { font-size: 1rem; font-weight: 800; color: var(--cf-warm); }

.cf-form-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.cf-tag-picker { display: flex; flex-wrap: wrap; gap: 7px; }

.cf-actions {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
}

.cf-actions-form { justify-content: space-between; }

.cf-status-line {
    margin: 0;
    font-size: 0.84rem;
    font-weight: 600;
    color: var(--cf-text-soft);
    line-height: 1.5;
}

/* ── TOOLBAR ── */
.cf-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.cf-filters { display: flex; flex-wrap: wrap; gap: 7px; }

/* ── CARD LISTS ── */
.cf-card-list { display: grid; gap: 10px; }

.cf-wide-card {
    display: grid;
    grid-template-columns: auto 1fr auto;
    align-items: center;
    gap: clamp(12px, 2vw, 22px);
    background: var(--cf-surface);
    border: 1px solid var(--cf-edge);
    border-radius: 16px;
    box-shadow: var(--card-shadow);
    padding: clamp(13px, 2vw, 20px);
    transition: border-color 0.16s ease;
}

.cf-wide-card:hover { border-color: var(--cf-edge-active); }

.cf-wide-card h2,
.cf-wide-card h3 {
    margin: 0 0 5px;
    font-size: 1.05rem;
    font-weight: 800;
    line-height: 1.3;
    color: var(--cf-warm);
}

.cf-wide-card p {
    margin: 0;
    font-size: 0.88rem;
    font-weight: 600;
    line-height: 1.5;
    color: var(--cf-text-soft);
}

.cf-meta {
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--cf-warm-faint);
    white-space: nowrap;
}

/* ── TAGS ── */
.cf-tag-row { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }

.cf-tag {
    display: inline-flex;
    align-items: center;
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(108, 188, 255, 0.12);
    color: var(--cf-cold);
    font-size: 0.72rem;
    font-weight: 800;
}

.cf-status-tag.is-open { background: rgba(34, 197, 94, 0.16); color: #4ade80; }
.cf-status-tag.is-solved { background: rgba(108, 188, 255, 0.16); color: var(--cf-cold); }
.cf-status-tag.is-closed { background: rgba(255, 255, 255, 0.08); color: var(--cf-text-soft); }

/* ── STATES ── */
.cf-empty,
.cf-loading,
.cf-error {
    border-radius: 16px;
    padding: 18px;
    font-weight: 700;
    font-size: 0.88rem;
    text-align: center;
}

.cf-empty {
    background: rgba(201, 179, 255, 0.05);
    color: var(--cf-text-soft);
    border: 1px dashed rgba(201, 179, 255, 0.3);
}

.cf-loading {
    background: rgba(108, 188, 255, 0.07);
    color: var(--cf-cold);
}

.cf-error {
    background: rgba(239, 68, 68, 0.1);
    color: #f87171;
}

/* ── DASHBOARD PANELS ── */
.cf-dashboard {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}

.cf-panel {
    background: var(--cf-surface);
    border: 1px solid var(--cf-edge);
    border-radius: 16px;
    box-shadow: var(--card-shadow);
    padding: clamp(13px, 2vw, 20px);
}

.cf-panel > strong { font-size: 0.95rem; font-weight: 800; color: var(--cf-warm); }

.cf-panel .cf-card-list { margin-top: 10px; }

/* ── DETAIL VIEW ── */
.cf-detail { display: grid; gap: 14px; }

.cf-detail > .cf-btn { justify-self: start; }

.cf-detail-card {
    background: var(--cf-surface);
    border: 1px solid var(--cf-edge);
    border-radius: 20px;
    box-shadow: var(--card-shadow);
    padding: clamp(18px, 3vw, 34px);
}

.cf-detail-card h1 {
    margin: 8px 0 0;
    font-family: "Fredoka", "Quicksand", sans-serif;
    font-size: clamp(1.5rem, 2.8vw, 2.1rem);
    font-weight: 600;
    line-height: 1.15;
    color: var(--cf-warm);
}

.cf-prose {
    margin-top: 14px;
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1.65;
    color: var(--cf-text);
    white-space: pre-wrap;
    word-break: break-word;
}

/* ── REPLIES ── */
.cf-reply-list { display: grid; gap: 10px; }

.cf-reply {
    background: rgba(255, 255, 255, 0.035);
    border: 1px solid rgba(201, 179, 255, 0.1);
    border-radius: 14px;
    padding: 12px 14px;
}

.cf-reply .cf-reply {
    margin-top: 9px;
    background: rgba(0, 0, 0, 0.5);
}

.cf-reply .cf-reply .cf-reply { background: rgba(255, 255, 255, 0.035); }

.cf-reply.is-admin { box-shadow: inset 0 0 0 1px var(--cf-edge-active); }
.cf-reply.is-staff { box-shadow: inset 0 0 0 1px rgba(34, 197, 94, 0.45); }

.cf-reply-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 9px;
    flex-wrap: wrap;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--cf-warm-faint);
}

.cf-reply-body {
    margin-top: 7px;
    font-size: 0.89rem;
    font-weight: 600;
    line-height: 1.55;
    color: var(--cf-text);
    white-space: pre-wrap;
    word-break: break-word;
}

.cf-role-badge {
    display: inline-flex;
    margin-left: 8px;
    padding: 2px 9px;
    border-radius: 999px;
    background: rgba(108, 188, 255, 0.18);
    color: var(--cf-cold);
    font-size: 0.66rem;
    font-weight: 800;
    vertical-align: middle;
}

.cf-role-badge.is-staff { background: rgba(34, 197, 94, 0.2); color: #4ade80; }

/* moderation dropdown built inline by the page scripts — its colours
   come from --cf-card-bg / --cf-line above */
.cf-moderation-menu {
    box-shadow: 0 20px 50px rgba(0, 0, 0, 0.6);
}

/* ─────────────────────────────────────────────────────────────
   THE NAV BAR, ON THESE PAGES ONLY

   cometfare-sky-header.css builds a bar that is NOT a surface: no
   background, just a black scrim fading downward, with periwinkle type
   floating over whatever the page puts up there. That is still exactly
   what index.html gets, and it must stay that way.

   On the five dark pages the relationship flips: the bar IS the surface,
   painted the same periwinkle the frame and the separator are made of,
   with everything on it in black.

   ⚠️ These overrides live HERE and nowhere else. cometfare-sky-header.css
   is shared with index.html (and every other page that loads it), so a
   change made there would repaint the landing page's nav too — which is
   explicitly not wanted. dark-pages.css is linked only by blog, discover,
   releases, support and voyager, and always AFTER the header stylesheet,
   so these win on load order without needing !important.
   ───────────────────────────────────────────────────────────── */

.sky-nav {
    background: var(--cf-warm);
}

/* the scrim was there to keep type readable over arbitrary page content;
   an opaque bar does that job itself, and the black haze only muddies
   the periwinkle */
.sky-nav::before,
.sky-nav.scrolled::before { opacity: 0; }

.sky-brand,
.sky-nav-trigger { color: #000000; }

/* engaged marks take a black outline instead of the blue one — blue is
   the landing page's selection colour and reads as a bruise on periwinkle */
.sky-brand:hover img,
.sky-brand:focus-visible img { outline-color: #000000; }

/* version squircle: was a black chip with periwinkle type sitting on a
   transparent bar. Inverted, it is an outlined chip on the periwinkle. */
.sky-brand-version {
    background: none;
    border: 2px solid #000000;
    color: #000000;
}

/* ── ENGAGED = INVERTED ──
   The header's one rule is "resting vs engaged". Off the black bar that
   was periwinkle → blue; on a periwinkle bar it becomes black type →
   black surface with periwinkle type. Same single signal, legible here. */
.sky-nav-group:hover .sky-nav-trigger,
.sky-nav-group:focus-within .sky-nav-trigger {
    color: var(--cf-warm);
    background: #000000;
    border-color: #000000;
}

/* the popup drawers under Product/App/Policy are left alone here — they
   keep the header stylesheet's own black-panel/periwinkle-text styling,
   unlike the bar itself which this file inverts. */

.sky-nav-cta {
    color: #000000;
    background: none;
    border: 2px solid #000000;
}

.sky-nav-cta:hover,
.sky-nav-cta:focus-visible {
    color: var(--cf-warm);
    background: #000000;
    border-color: #000000;
}

/* ── MISC ── */
.cf-hidden { display: none !important; }

@media (max-width: 860px) {
    .cf-dashboard,
    .cf-form-grid { grid-template-columns: 1fr; }

    .cf-wide-card {
        grid-template-columns: 1fr;
        align-items: start;
    }

    .cf-wide-card .cf-actions { justify-content: flex-start; }

    .cf-search { max-width: 100%; }
}
