/* PythonMastery — site chrome: the header nav and the page footer.
 *
 * ONE definition, loaded by every page. Before this there were three navs — the
 * generated pages' `nav.nav`, index.html's `.grid-header .nav`, and a hand-built
 * `.landscape-console-nav` that the IDE swaps in when it hides the header in
 * landscape. The third had been written when the site had two destinations and
 * still listed two, so on a phone held sideways the Playground and the Notebook
 * simply did not exist. Three copies of a nav is three chances to forget one.
 *
 * The two stylesheets on this site name the same palette differently —
 * academy-build.css calls it `--fg-2`, styles.css calls it `--text-secondary`,
 * and both resolve to #94a3b8. Every colour here is written as a fallback chain
 * through both, so this file drops into either page without a token shim:
 *
 *     var(--fg-2, var(--text-secondary, #94a3b8))
 *
 * That ordering matters: academy tokens first, because on generated pages both
 * sets may be present and the academy one is authoritative there.
 */

:root {
    --chrome-fg:      var(--fg,     var(--text-primary,   #f8fafc));
    --chrome-fg-2:    var(--fg-2,   var(--text-secondary, #94a3b8));
    /* --chrome-muted lets a page lift the footer's small print where its own
       muted colour is too dim for it; styles.css (the IDE pages) does. */
    --chrome-fg-3:    var(--chrome-muted, var(--fg-3, var(--text-muted, #64748b)));
    --chrome-line:    var(--line,   var(--border-main,    rgba(248,250,252,0.12)));
    --chrome-line-2:  var(--line-2, var(--border-main,    rgba(248,250,252,0.20)));
    --chrome-accent:  var(--accent, var(--accent-primary, #38bdf8));
    --chrome-bg-2:    var(--bg-2,   var(--bg-secondary,   #1e293b));
}

/* ─── Header nav ──────────────────────────────────────────────────────────── */

.nav,
.grid-header .nav {
    display: flex;
    align-items: center;
    gap: 26px;
    min-width: 0;
}

/* The current page is a <span>, not an <a> — a nav marks where you are, and the
   item for the page you are already on should not be a link that reloads it.
   Selectors match both element types throughout. */
.nav a,
.nav [aria-current="page"],
.grid-header .nav a,
.grid-header .nav [aria-current="page"] {
    position: relative;
    color: var(--chrome-fg-2);
    text-decoration: none;
    font-size: 0.91rem;
    font-weight: 500;
    white-space: nowrap;
    padding-bottom: 2px;
    transition: color 0.15s;
}

.nav a:hover,
.grid-header .nav a:hover { color: var(--chrome-fg); }

.nav [aria-current="page"],
.grid-header .nav [aria-current="page"] { color: var(--chrome-fg); }

.nav [aria-current="page"]::after,
.grid-header .nav [aria-current="page"]::after {
    content: "";
    position: absolute;
    left: 0; right: 0; bottom: -4px;
    height: 2px;
    border-radius: 2px;
    background: var(--chrome-accent);
}

/* Tablets and large phones: the row still fits, it just needs less air.
   The padding covers BOTH the links and the current-page <span> -- padding only
   the links left the item for the page you were on sitting 4px low and 8px
   short, which is the kind of misalignment you see without being able to name. */
@media (max-width: 860px) {
    .nav, .grid-header .nav { gap: 20px; }
    .nav a, .nav [aria-current="page"],
    .grid-header .nav a, .grid-header .nav [aria-current="page"] {
        display: inline-block;
        padding: 8px 0;
    }
    .nav [aria-current="page"]::after,
    .grid-header .nav [aria-current="page"]::after { bottom: 2px; }
}

/* Phones and tablets: ONE row, always, portrait or landscape.
 *
 * Four labels at 0.91rem need ~276px of text plus gaps, which does not fit the
 * 256px content box of a folded Fold. The earlier answer was a 2x2 block; this
 * one keeps the single row and scales the type to the viewport instead, because
 * a nav that changes shape between devices reads as two different navs.
 *
 * clamp() rather than a stack of breakpoints so the size moves continuously --
 * there is no width at which the row is suddenly cramped, and no width at which
 * it jumps. The lower bound of 0.70rem is ~11px, which is small but legible;
 * space-between spreads the row edge to edge so the tightness reads as a
 * deliberate layout rather than as text that failed to fit.
 */
@media (max-width: 560px) {
    .nav, .grid-header .nav {
        display: flex;
        flex-wrap: nowrap;
        justify-content: space-between;
        align-items: center;
        width: 100%;
        gap: clamp(6px, 2.4vw, 18px);
    }
    .nav a, .nav [aria-current="page"],
    .grid-header .nav a, .grid-header .nav [aria-current="page"] {
        flex: 0 0 auto;
        white-space: nowrap;
        font-size: clamp(0.70rem, 3.0vw, 0.88rem);
        padding: 9px 0 7px;          /* keeps a ~38px touch target */
    }
    .nav [aria-current="page"]::after,
    .grid-header .nav [aria-current="page"]::after { bottom: 3px; }
}

/* ─── Page footer ─────────────────────────────────────────────────────────── */
/* Was one undifferentiated row of seven links, which is how /notebook/ and
   /datasets/ ended up invisible: present, but weighted the same as "terms". */

.foot {
    display: block;
    border-top: 1px solid var(--chrome-line);
    margin-top: 48px;
    /* padding-block, never the shorthand: `padding: 32px 0 44px` zeroes the
       inline sides, which silently wiped the gutter .foot-standalone sets. */
    padding-block: 32px 44px;
    font-size: 0.84rem;
    color: var(--chrome-fg-3);
}

/* Generated pages put the footer inside .shell, which supplies the max-width and
   the side gutter. The IDE landing has no .shell, so the footer there was running
   edge to edge and its ancestor's flex layout was pulling the copyright line up
   beside the columns. This variant carries its own container. */
.foot-standalone {
    max-width: var(--max, 1180px);
    margin-inline: auto;
    padding-inline: 24px;
    width: 100%;
}
@media (max-width: 660px) { .foot-standalone { padding-inline: 18px; } }
@media (max-width: 480px) { .foot-standalone { padding-inline: 16px; } }

.foot-nav {
    display: grid;
    gap: 26px 40px;
    grid-template-columns: repeat(auto-fit, minmax(min(180px, 100%), 1fr));
    max-width: 760px;
}

.foot-col {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 9px;
    min-width: 0;
}

.foot-h {
    margin: 0 0 2px;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--chrome-fg-3);
    opacity: 0.8;
}

.foot a,
.foot .foot-contact {
    color: var(--chrome-fg-2);
    text-decoration: none;
    font-size: 0.86rem;
    background: none;
    border: 0;
    padding: 0;
    cursor: pointer;
    font-family: inherit;
    text-align: left;
    /* Same 0.15s the header nav uses, for the same reason: a link that changes
       colour instantly reads as a redraw, not as a response. */
    transition: color 0.15s;
}

.foot a:hover,
.foot .foot-contact:hover { color: var(--chrome-accent); }

.foot-base {
    display: flex;
    flex-wrap: wrap;
    gap: 6px 16px;
    align-items: baseline;
    margin-top: 30px;
    padding-top: 18px;
    border-top: 1px solid var(--chrome-line);
}

.foot-stamp {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.74rem;
    color: var(--chrome-fg-3);
}

.foot-claim { font-size: 0.78rem; color: var(--chrome-fg-3); }

@media (hover: none), (max-width: 680px) {
    /* Navigation, not prose. 5px of padding measured 26px tall — short of the
       32px floor — so 11px, which lands at 38. */
    .foot a, .foot .foot-contact { padding: 11px 0; }
    .foot-col { gap: 2px; }
    .foot { margin-top: 36px; padding-block: 26px 34px; }
    .foot-nav { gap: 22px 28px; }
}

/* Brand red: the Indent mark's colon and cursor. A shade lighter on the dark
 * theme so the loading cursor holds contrast there. */
:root { --pm-red: #FF6A4D; }
/* :root[...] only: a bare [data-theme] also matches <body> and the theme buttons,
   which then hold their own copy that never fades. */
:root[data-theme="light"], :root[data-theme="eye-saver"] { --pm-red: #D9412B; }
.pm-mark .ink { fill: currentColor; }
.pm-mark .red { fill: var(--pm-red); }

/* The brand cursor: the loading indicator wherever Python is starting up (IDE
 * status badge, lesson toast, notebook status) -- the mark's cursor, blinking at
 * the terminal rate. Here because every page loads this file, index.html included. */
.pm-cursor {
    display: inline-block; flex-shrink: 0;
    width: 0.55em; height: 1.05em; vertical-align: -0.18em;
    background: var(--pm-red);
    animation: pm-cursor-blink 1.06s infinite;
}
@keyframes pm-cursor-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .pm-cursor { animation: none; } }

/* Wordmark on pages whose header is not .brand (index.html, privacy, terms). */
.brand-wordmark {
    font-family: 'Bricolage Grotesque', 'Inter', sans-serif; font-weight: 700;
    letter-spacing: -0.03em; color: var(--chrome-fg);
}

/* ─── Theme switch: one fade list for every page ────────────────────────────
 * A theme switch fades by animating registered colour tokens on :root for 300ms
 * while every element's own transition is off. Three stylesheets each declared
 * that list (styles.css, academy-build.css, tutorial-lab.css) and on a page that
 * loads two of them the later one REPLACED the other: on the Tutorial Lab the
 * header, nav and breadcrumb (academy tokens) snapped while the lab faded.
 * Tokens that were never registered (--fg-chrome, --pm-red, the lab's count
 * bubbles) can only snap, whatever the list says. This file loads last on every
 * page, so its list wins: the union of all three, plus the tokens that were
 * missing. Lines keep their deliberate 80ms step (see styles.css --border-main
 * and academy-build.css --line: a flipping hairline eased against its own
 * background vanishes at the midpoint). */
@property --fg-chrome  { syntax: '<color>'; inherits: true; initial-value: #a3b2c4; }
@property --pm-red     { syntax: '<color>'; inherits: true; initial-value: #FF6A4D; }
@property --pill-bg    { syntax: '<color>'; inherits: true; initial-value: #334155; }
@property --pill-fg    { syntax: '<color>'; inherits: true; initial-value: #a3b2c4; }
@property --pill-border{ syntax: '<color>'; inherits: true; initial-value: rgba(248, 250, 252, 0.12); }
@property --ok-text    { syntax: '<color>'; inherits: true; initial-value: #34d399; }

/* Literal per-theme values on purpose: a registered token that points at
   another animating token re-resolves every frame and restarts its own fade. */
:root, :root[data-theme="dark"] {
    --pill-bg: #334155; --pill-fg: #a3b2c4; --pill-border: rgba(248, 250, 252, 0.12); --ok-text: #34d399;
}
:root[data-theme="light"] {
    --pill-bg: #cbd5e1; --pill-fg: #4b5866; --pill-border: rgba(51, 65, 85, 0.12); --ok-text: #047857;
}
:root[data-theme="eye-saver"] {
    --pill-bg: #f6eedb; --pill-fg: #5c4a2a; --pill-border: #d9c9a3; --ok-text: #065f46;
}

:root[data-theme-transitioning] {
    transition:
        /* styles.css (IDE, lab, legal pages) */
        --bg-body 0.3s ease, --bg-main 0.3s ease, --bg-panel 0.3s ease,
        --bg-secondary 0.3s ease, --bg-tertiary 0.3s ease,
        --bg-workspace 0.3s ease, --bg-console 0.3s ease,
        --text-primary 0.3s ease, --text-secondary 0.3s ease, --text-muted 0.3s ease,
        --accent-primary 0.3s ease, --accent-hover 0.3s ease,
        --accent-green 0.3s ease, --accent-red 0.3s ease, --accent-yellow 0.3s ease,
        --bg-input 0.3s ease, --bg-input-focus 0.3s ease,
        --accent-green-bg 0.3s ease, --accent-red-bg 0.3s ease, --accent-yellow-bg 0.3s ease,
        --bg-nav-glass 0.3s ease, --bg-card-glass 0.3s ease,
        /* academy-build.css (generated pages, and the lab's shared header) */
        --fg 0.3s ease, --fg-2 0.3s ease, --fg-3 0.3s ease, --fg-4 0.3s ease,
        --bg 0.3s ease, --bg-2 0.3s ease, --bg-3 0.3s ease,
        --bg-code 0.3s ease, --bg-out 0.3s ease,
        --accent 0.3s ease, --accent-soft 0.3s ease,
        --run 0.3s ease, --run-deep 0.3s ease,
        --good 0.3s ease, --good-soft 0.3s ease,
        --warn 0.3s ease, --warn-soft 0.3s ease, --err 0.3s ease,
        --syn-kw 0.3s ease, --syn-str 0.3s ease, --syn-com 0.3s ease,
        --syn-fn 0.3s ease, --syn-num 0.3s ease,
        /* tutorial-lab.css */
        --lab-bg 0.3s ease, --lab-surface 0.3s ease, --lab-surface-hover 0.3s ease,
        --lab-text 0.3s ease, --lab-text-secondary 0.3s ease,
        --lab-accent 0.3s ease, --lab-accent-hover 0.3s ease,
        --lab-success 0.3s ease, --lab-error 0.3s ease, --lab-warning 0.3s ease,
        --lab-count-bg 0.3s ease, --lab-count-fg 0.3s ease,
        --lab-diff-basic 0.3s ease, --lab-diff-intermediate 0.3s ease, --lab-diff-advanced 0.3s ease,
        /* brand + header pills (registered above) */
        --fg-chrome 0.3s ease, --pm-red 0.3s ease,
        --pill-bg 0.3s ease, --pill-fg 0.3s ease, --ok-text 0.3s ease,
        /* LINES step at 80ms, never ease */
        --border-main 1ms linear 80ms, --line 1ms linear 80ms, --line-2 1ms linear 80ms,
        --line-3 1ms linear 80ms, --accent-line 1ms linear 80ms, --lab-border 1ms linear 80ms,
        --pill-border 1ms linear 80ms;
}
@media (prefers-reduced-motion: reduce) {
    :root[data-theme-transitioning] { transition: none !important; }
}

/* View Transitions cross-fade (theme-fab.js withViewTransition). The browser
 * snapshots the old theme, applies the new one at once, and fades between the
 * two pictures. The token animation above must NOT also run underneath, or the
 * live "new" picture would still be mid-fade. */
:root[data-theme-vt][data-theme-transitioning] { transition: none !important; }
::view-transition-old(root),
::view-transition-new(root) { animation-duration: 0.3s; animation-timing-function: ease; }
