/* === BEGIN base.css (inlined to avoid @import waterfall) === */
/* DO NOT DELETE THIS BLOCK AS "DEAD CODE". Two separate review passes have now
   proposed removing it — most recently with the confident claim that no page
   loading this file renders any of its selectors — and both were wrong.

   Measured: the block holds 130 rules, and 114 of them are declared NOWHERE else
   in any stylesheet that loads on these pages. They include load-bearing
   behaviour, not leftovers:

     html[data-font-size="small|medium|large|xlarge"]   the text-size preference
     body.ui-mobile-optimized, body.ui-touch            the mobile layout
     body.ui-high-contrast, body.ui-reduce-motion       the a11y preferences
     header, .hidden, .success-message, .text-center    utilities used everywhere

   It is true that this region began as an inlined copy of the old base.css and
   puzzles.css, and that a good many of its 130 rules ARE leftovers from
   components no template emits any more — those have been pruned individually,
   by selector, more than once. The mass of it is not dead; the appearance of
   being dead survives because the class names are generic and the markup that
   uses them is spread across templates and JS.

   If you want to reduce it further, do it rule by rule against the rendered HTML
   of every page that links this file — the way the 63 removed rules were chosen —
   and never by deleting the range. */

/* Base styles for common elements */
body {
    display: flex;
    flex-direction: column;
    align-items: center;
    min-height: 100vh;
    margin: 0;
    /* The decorative radial-gradient/linear-gradient background that used to be
       here (orange + cyan blobs over a teal base) is gone: design tokens now own
       the page surface (see public/css/tokens.css), which loads before this file
       and resets background-image explicitly. */
    padding-bottom: 50px;
    /* Was a hard-coded `Arial, sans-serif`, which silently won the cascade
       against the design system and stopped the whole site's body copy from ever
       rendering in Figtree. Body type is a token. */
    font-family: var(--font-body);
}

/* Accessibility helpers */
body.ui-high-contrast {
    background-color: #000;
    color: #fff;
}

body.ui-high-contrast header,
body.ui-high-contrast nav,
body.ui-high-contrast .intro,
body.ui-high-contrast .form-container,
body.ui-high-contrast .stat-card,
body.ui-high-contrast .achievements-section,
body.ui-high-contrast .stats-section,
body.ui-high-contrast .recent-activity,
body.ui-high-contrast .activity-item {
    background-color: #000;
    color: #fff;
    border-color: #fff;
    box-shadow: none;
}

body.ui-high-contrast nav a {
    color: #0ff;
}

body.ui-high-contrast .button,
body.ui-high-contrast button,
body.ui-high-contrast .template-action {
    background-color: #111;
    color: #0ff;
    border: 1px solid #0ff;
}

/* Text-size preference.
   -------------------------------------------------------------------------
   These set <html>, not <body>, and that is the whole point. `rem` resolves
   against the ROOT element, so `body[data-font-size="xlarge"] { font-size: 20px }`
   — what stood here — changed the size of the body box and nothing else. Measured
   by toggling the setting in the browser:

       medium -> xlarge     body copy  19px -> 19px    (unchanged)
                            footer     14px -> 14px    (unchanged)
                            heading    34px -> 34px    (unchanged)
                            nav link   16px -> 20px    (changed, by inheritance)

   One of five probes moved. The Small/Medium/Large/Extra-large control was, in
   effect, inert on a site whose type is almost entirely rem-based — so a visitor
   who needs larger text could not get it, which is WCAG 1.4.4 (Resize Text).

   Percentages rather than px so the browser's own default font size is
   preserved and scaled, which is what a text-size preference should do. Spacing
   and the type scale are rem-based and now scale with it; radii are px and
   deliberately do not. */
html[data-font-size="small"]  { font-size: 87.5%; }
html[data-font-size="medium"] { font-size: 100%; }
html[data-font-size="large"]  { font-size: 112.5%; }
html[data-font-size="xlarge"] { font-size: 125%; }

body.ui-reduce-motion * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
}

/* A GUARANTEED focus indicator, in the brand accent rather than Windows blue.
   -------------------------------------------------------------------------
   This replaces `*:focus-visible { outline: 3px solid #0078d7 }` — a hardcoded
   Windows blue at (0,1,0) that, loading after tokens.css, beat the site's own
   `:focus-visible { box-shadow: var(--focus-ring) }` and made every focus
   indicator off-palette.

   Deleting it outright, which was my first attempt, turned out to be a
   REGRESSION, and only tabbing through the real page showed it. The token rule
   expresses the ring as a box-shadow, and components that set their own
   box-shadow — `.big-btn`, `.cookie-modal__btn`, cards — overwrite it. Measured
   by pressing Tab in Chromium:

       .cookie-modal__btn   focus-visible  outline: none  box-shadow: none
       .big-btn secondary   focus-visible  outline: none  box-shadow: none
       .big-btn primary     focus-visible  outline: none  box-shadow: <drop>
       .hero-cube           focus-visible  box-shadow: 0 0 0 3px (token)  OK
       .daily-card          focus-visible  box-shadow: 0 0 0 2.5px (token) OK

   Three interactive controls had no visible focus at all. So the outline is back,
   but tokenised, and `!important` is deliberate and justified here: a focus ring
   is an accessibility guarantee that no component should be able to swallow,
   which is the one case where a plain element selector has to outrank class
   rules. `outline-offset` keeps the ring clear of the control's own edge, so it
   sits on the page background and stays legible even on accent-filled buttons. */
:focus-visible {
    outline: 3px solid var(--accent) !important;
    outline-offset: 2px;
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* The mobile-optimisation rules that used to sit here — the 12px body padding and
   the 44px minimum touch targets — now live in public/css/chrome.css.
   -------------------------------------------------------------------------
   They were in this file, which only the main column of the site loads: /3d and
   every /play/* and /3d/* puzzle page do not, so on those pages the touch targets
   were never applied and the 12px body padding was missing. Measured at 390x844:

       /play/sudoku   3 buttons,  ALL under 44px (29px tall)
       /play/crossword 16 buttons, ALL under 44px
       /3d/tiles      6 buttons,  ALL under 44px, one of them 24x14px — under even
                                  the 24x24 minimum of WCAG 2.5.8

   chrome.css is emitted by Navigation::criticalStylesheets() on every page, which
   is where a rule that is meant to apply to every page belongs. */
body.ui-touch input,
body.ui-mobile-optimized input,
body.ui-touch select,
body.ui-mobile-optimized select,
body.ui-touch textarea,
body.ui-mobile-optimized textarea,
html[data-ui-touch] body input,
html[data-ui-mobile] body input,
html[data-ui-touch] body select,
html[data-ui-mobile] body select,
html[data-ui-touch] body textarea,
html[data-ui-mobile] body textarea {
    min-height: 44px;
    font-size: 1rem;
}

@media (max-width: 768px) {
    .intro,
    .form-container,
    .stats-section,
    .achievements-section,
    .recent-activity {
        width: 100%;
        max-width: 100%;
        padding: 16px;
        margin: 0 0 16px 0;
    }

    nav a {
        margin: 0 10px;
    }

    .template-actions__inner {
        gap: 8px;
    }

    .login-card,
    .register-card,
    .error-card {
        width: calc(100% - 1.5rem) !important;
        margin: 1rem auto !important;
        padding: 1.25rem !important;
    }

    .form-group {
        margin-bottom: 1rem;
    }

    .form-group label {
        display: block;
        margin-bottom: 0.35rem;
    }

    .form-label {
        width: auto;
        margin-right: 0;
        margin-bottom: 0.35rem;
        text-align: left;
    }

    .login-button,
    .register-button {
        width: 100%;
        margin-top: 0.5rem;
    }

    .register-link,
    .login-link {
        text-align: center;
        margin-top: 1rem;
    }
}

/* Header and Navigation */
header {
    /* Was a hard-coded #333 band. Any <header> without its own background got a
       dark strip that fights the surface tokens — blog.css even carries a comment
       working around it, and adds a [data-theme="light"] override just to make the
       blog header readable. Component headers (.site-header, .blog-header,
       .article-hero) already set their own surfaces, so this is only the fallback
       and now follows the theme. */
    background-color: var(--bg-2);
    padding: 10px;
    width: 100%;
    text-align: center;
    flex-shrink: 0;
}

/* A bare `nav {}` / `nav a {}` pair stood here, left over from the original site
   header — a centred row of white, 20px-margined links on a dark bar.
   -------------------------------------------------------------------------
   Because they were ELEMENT selectors they applied to every <nav> in the
   application, not just the header, and `nav a` at (0,0,2) outranked the global
   `a {}` rule at (0,0,1). On the four legal pages that painted `.legal-links`
   white on the cream page background — 1.06:1, invisible rather than merely low
   contrast, which is what Lighthouse was reporting on /privacy.

   There are five <nav> elements in the codebase and every one now carries its own
   class with its own styling: `.site-header__nav`, `.footer-links`, `.legal-links`,
   `.account-tabs`, `.leaderboard-pagination`. Two of them were silently relying on
   this rule for `justify-content: center`, and both now state it themselves in
   chrome.css. Nothing else used it. */

.nav-image {
    width: 30px;
    height: 30px;
    margin-left: 10px;
}

/* Common Components */
.intro {
    text-align: center;
    margin: 20px 0;
    padding: 20px;
    border: 1px solid #333;
    background-color: #fff;
    border-radius: 10px;
    width: 80%;
    max-width: 800px;
    flex-shrink: 0;
}

.form-label {
    font-weight: normal;
    text-align: right;
    margin-right: 10px;
    width: 80px;
    flex-shrink: 0;
}

/* Buttons */
.button {
    padding: 5px 15px;
    cursor: pointer;
    background-color: #f0f0f0;
    color: #333;
    border: 1px solid #ccc;
    border-radius: 4px;
    transition: background-color 0.2s;
}

.button:hover {
    background-color: #e0e0e0;
}

/* Tables */
table {
    border-collapse: collapse;
    margin: 20px;
}

td {
    width: 30px;
    height: 30px;
    border: 1px solid #000;
    text-align: center;
    vertical-align: middle;
    padding: 2px;
}

/* Messages */
.error-message {
    color: red;
    text-align: center;
    margin-bottom: 10px;
}

.success-message {
    color: green;
    text-align: center;
    margin-bottom: 10px;
}

/* Utility Classes */
.hidden {
    display: none;
}

.text-center {
    text-align: center;
}

/* Stats Grid */
.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 20px;
    margin-top: 20px;
}

.stat-details p {
    margin: 5px 0;
    color: var(--text);
}

.achievement-icon {
    font-size: 2em;
    width: 50px;
    height: 50px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #fff;
    border-radius: 50%;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}

/* Activity Timeline */
.activity-timeline {
    margin-top: 20px;
}

/* Responsive Adjustments */
@media (max-width: 768px) {
    .stats-grid,
    .achievements-grid {
        grid-template-columns: 1fr;
    }

}

.button-title {
    margin-top: 10px;
    font-size: 14px;
    font-weight: bold;
    color: #333;
}

.puzzle-controls {
    display: flex;
    justify-content: space-between;
    margin-bottom: 20px;
}

.puzzle-button {
    margin: 10px;
    padding: 8px 16px;
    font-size: 14px;
    cursor: pointer;
}

.cell {
    width: 40px;
    height: 40px;
    border: 2px solid #000;
    position: absolute;
    transition: transform 0.3s ease-in-out;
}

.innerTop, .innerBottom {
    width: 100%;
    height: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.innerBottom {
    background-color: #e0dcdd;
    text-transform: uppercase;
}

.entered {
    background-color: white;
}

/* Timer Styles */
.timer-area {
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
    margin: 2rem 0;
}

#clock {
    width: 100px;
    height: 100px;
    border: 4px solid #333;
    border-radius: 50%;
    position: relative;
    margin: 20px auto;
    background: white;
}

.hand {
    position: absolute;
    bottom: 50%;
    left: 50%;
    transform-origin: bottom;
    background: #333;
    transition: transform 0.5s cubic-bezier(0.4, 2.5, 0.36, 0.75);
}

#hour {
    width: 2px;
    height: 25px;
    margin-left: -1px;
}

#minute {
    width: 2px;
    height: 35px;
    margin-left: -1px;
}

#second {
    width: 1px;
    height: 40px;
    background: #F44336;
    margin-left: -0.5px;
}

.number {
    position: absolute;
    font-size: 0.75rem;
    font-weight: bold;
    color: #333;
}

#number12 { top: 5px; left: 50%; transform: translateX(-50%); }
#number3 { right: 5px; top: 50%; transform: translateY(-50%); }
#number6 { bottom: 5px; left: 50%; transform: translateX(-50%); }
#number9 { left: 5px; top: 50%; transform: translateY(-50%); }

#digitaltimer {
    font-family: var(--font-mono);
    font-size: 1.5rem;
    font-weight: bold;
    margin-top: 10px;
    color: #333;
}

/* Cipher Table */
.cipher-table {
    margin-top: 20px;
    display: table;
    width: 100%;
    border-collapse: collapse;
}

.cipher-row {
    display: table-row;
}

/* Tabs */
.tab-container {
    display: flex;
    justify-content: center;
    margin: 20px 0;
}

.tab-content {
    width: 90%;
    max-width: 1000px;
    margin-top: 20px;
    flex-grow: 1;
}

.hidden-content {
    display: none;
}

/* Sudoku Grid Styles */
.sudoku-grid {
    display: grid;
    grid-template-columns: repeat(9, 45px);
    grid-template-rows: repeat(9, 45px);
    gap: 1px;
    background-color: #333;
    border: 2px solid #333;
    width: fit-content;
    margin: 20px auto;
}

.sudoku-cell {
    background-color: white;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 20px;
    cursor: pointer;
    -webkit-user-select: none;
    user-select: none;
    position: relative;
}

.sudoku-cell.given {
    font-weight: bold;
    background-color: #f0f0f0;
}

.sudoku-cell.selected {
    background-color: #e3f2fd;
}

.border-left {
    border-left: 2px solid #333;
}

.border-top {
    border-top: 2px solid #333;
}

/* Number Pad */
.number-pad {
    margin: 20px auto;
    width: fit-content;
}

.number-buttons {
    display: grid;
    grid-template-columns: repeat(5, 45px);
    gap: 5px;
}

.number-button {
    width: 45px;
    height: 45px;
    font-size: 20px;
    border: 1px solid #ccc;
    background-color: white;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.2s;
}

.number-button:hover {
    background-color: #e3f2fd;
}

.number-button[data-number="0"] {
    grid-column: span 2;
    width: 95px;
    font-size: 16px;
}

/* Template puzzle pages: centralized styles moved from inline blocks */
.word-grid { user-select: none; -webkit-user-select: none; touch-action: none; }
.cell { touch-action: none; cursor: pointer; }
.cell:hover { background-color: rgba(255,255,255,0.02); }
.cell.selected { background-color: rgba(59,130,246,0.12); }
.cell.found { background-color: var(--color-success); color: white; }
.cell.hint-cell { background-color: rgba(245,158,11,0.12); animation: ws-pulse 1s infinite; }
@keyframes ws-pulse { 0%,100%{opacity: 1;}50%{opacity: 0.5;} }
.word-list h3{ margin-top: 0; }

.logic-cell { transition: background-color 0.3s ease; }
.logic-cell:hover { background-color: #e0e0e0; }
.logic-cell.selected { background-color: #90caf9; }
.logic-cell.incorrect { background-color: #ffcccc; animation: logic-shake 0.5s; }
.logic-cell[aria-selected="true"] { outline: 2px solid #2196f3; outline-offset: -2px; }
@keyframes logic-shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }

.action-buttons { display: flex; gap: 10px; justify-content: center; margin: 10px 0; }
.action-buttons button { padding: 8px 16px; border: none; border-radius: 5px; cursor: pointer; font-size: 14px; transition: background 0.3s; }
.action-buttons button:hover { background: #ddd; }
.action-buttons button:disabled { opacity: 0.5; cursor:not-allowed; }

.statistics-panel { display: flex; gap: 15px; justify-content: center; margin: 10px 0; padding: 10px; background: #f0f0f0; border-radius: 8px; }
.stat-item { font-weight: bold; color: #333; }
.clue-item { padding: 5px; border-bottom: 1px solid #eee; }
.clue-item:hover { background-color: #f9f9f9; }

.pencil-mode-active .sudoku-cell.selected::after {
    content: '✏️';
    position: absolute;
    top: 2px;
    right: 2px;
    font-size: 10px;
}

.pencil-mark-container {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    width: 100%;
    height: 100%;
    font-size: 10px;
}

.pencil-mark { display: flex; align-items: center; justify-content: center; color: #666; }
.top-left { grid-column: 1; grid-row: 1; }
.top-center { grid-column: 2; grid-row: 1; }
.top-right { grid-column: 3; grid-row: 1; }
.middle-left { grid-column: 1; grid-row: 2; }
.middle-center { grid-column: 2; grid-row: 2; }
.middle-right { grid-column: 3; grid-row: 2; }
.bottom-left { grid-column: 1; grid-row: 3; }
.bottom-center { grid-column: 2; grid-row: 3; }
.bottom-right { grid-column: 3; grid-row: 3; }

.sudoku-cell.incorrect { background-color: #ffcccc; animation: sudoku-shake 0.5s; }
.sudoku-cell.hint-cell { background-color: #ccffcc; }
@keyframes sudoku-shake { 0%, 100% { transform: translateX(0); } 25% { transform: translateX(-5px); } 75% { transform: translateX(5px); } }
.pencil-toggle.active { background: #4CAF50; color: white; }
.score-display { margin-top: 20px; text-align: center; }
.score-display div { margin: 5px 0; font-size: 16px; }

.tab-content--visible { display: block; }
.panel-hidden { display: none; }

.keyboard-shortcuts {
    text-align: center;
    margin-top: 20px;
    font-size: 0.75rem;
    color: #666;
}

/* Difficulty Controls */
.difficulty-controls {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 20px 0;
}

#difficulty-select {
    padding: 0.5rem;
    border: 2px solid #ddd;
    border-radius: 4px;
    font-size: 1rem;
    cursor: pointer;
}

/* Logic Grid Styles */
.logic-grid-container {
    display: flex;
    gap: 2rem;
    padding: 2rem;
    max-width: 1200px;
    margin: 0 auto;
}

.clues-panel {
    flex: 0 0 300px;
    background: #f5f5f5;
    padding: 1rem;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.clues-list {
    max-height: 600px;
    overflow-y: auto;
}

.clue {
    padding: 0.5rem;
    margin: 0.5rem 0;
    background: white;
    border-radius: 4px;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}

.grid-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.symbol-controls {
    display: flex;
    gap: 1rem;
    padding: 1rem;
    background: #f5f5f5;
    border-radius: 8px;
}

.symbol-button {
    font-size: 1.5rem;
    width: 40px;
    height: 40px;
    border: 2px solid #ddd;
    border-radius: 4px;
    background: white;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
}

.symbol-button:hover {
    background-color: #f0f0f0;
}

.symbol-button.selected {
    border-color: #4CAF50;
    background: #E8F5E9;
}

.symbol-button[data-symbol="none"] {
    font-size: 14px;
    width: auto;
    padding: 0 10px;
}

.logic-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 2rem;
    padding: 1rem;
    background: #f5f5f5;
    border-radius: 8px;
}

.logic-subgrid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 2px;
    background: #ddd;
    padding: 4px;
    border-radius: 4px;
}

.subgrid-header {
    grid-column: 1 / -1;
    padding: 0.5rem;
    background: #333;
    color: white;
    text-align: center;
    font-weight: bold;
    border-radius: 2px;
    margin-bottom: 4px;
}

.logic-cell {
    aspect-ratio: 1;
    background: white;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 1.5rem;
    transition: all 0.2s;
}

.logic-cell:hover {
    background: #f0f0f0;
}

.logic-cell.circle::before {
    content: "○";
    color: #4CAF50;
}

.logic-cell.cross::before {
    content: "×";
    color: #F44336;
}

.logic-cell.correct {
    background-color: #e8f5e9;
}

.logic-cell.incorrect {
    background-color: #ffebee;
}

/* Controls section */
.controls-section {
    display: flex;
    gap: 1rem;
    padding: 1rem;
    justify-content: center;
    background: #f5f5f5;
    border-radius: 8px;
    margin-bottom: 1rem;
}

.button {
    padding: 0.5rem 1rem;
    border: none;
    border-radius: 4px;
    background: #4CAF50;
    color: white;
    font-weight: bold;
    cursor: pointer;
    transition: background 0.2s;
}

.button:hover {
    background: #45a049;
}
/* === END puzzles.css === */

/* The theme token block that used to live here has been deleted.
   It re-declared --bg-*, --text, --brand, --brand-2, --line, --ok/--warn/--danger
   and --shadow-*, and because this file loads AFTER public/css/tokens.css at
   equal specificity, the OLD palette silently won the cascade: --brand resolved
   to brick var(--accent) in light mode and pink var(--accent) in dark mode, while --accent
   (defined only in tokens.css) stayed petrol. That is why the brand colour, the
   login button and the accent disagreed on the same page. Design tokens now have
   exactly one home: public/css/tokens.css. */
html[data-theme="light"] body {
    background-color: var(--bg-0);
    background-image: none;
}

html[data-theme="light"] .login-card h1,
html[data-theme="light"] .register-card h1,
html[data-theme="light"] .error-card h1,
html[data-theme="light"] .not-logged-card h1,
html[data-theme="light"] .leaderboard-header h1,
html[data-theme="light"] .page-header h1,
html[data-theme="light"] .hero h1,
html[data-theme="light"] .about-container > .hero h1 {
    background: none;
    -webkit-text-fill-color: currentColor;
    color: var(--text-strong);
}

/* Hero band. This was a hard-coded blush (#e8d5cc) fading into the page — the
   only warm-pink surface left on the site, and the old brand's "Soft Blush"
   showing through the new palette as a stray pink band behind the About
   heading. The surface tint now comes from the inset token, so it reads as a
   raised panel rather than a different colour family. */
.hero {
    background: linear-gradient(135deg, var(--bg-2), var(--bg-0));
}

html[data-theme="light"] .form-group label,
html[data-theme="light"] .filter-group label,
html[data-theme="light"] .form-label {
    color: var(--text-strong) !important;
}

html[data-theme="light"] .form-group input,
html[data-theme="light"] .form-group select,
html[data-theme="light"] .form-group textarea,
html[data-theme="light"] .form-input,
html[data-theme="light"] input[type='text'],
html[data-theme="light"] input[type='password'],
html[data-theme="light"] input[type='email'],
html[data-theme="light"] input[type='number'],
html[data-theme="light"] input[type='datetime-local'],
html[data-theme="light"] select,
html[data-theme="light"] textarea {
    border-color: color-mix(in srgb, var(--text) 22%, transparent) !important;
    background: rgba(253, 251, 249, 0.9) !important;
}

html[data-theme="light"] th {
    color: var(--text-strong) !important;
}

html[data-theme="light"] .stat-number,
html[data-theme="light"] .rank-number,
html[data-theme="light"] .stat-value,
html[data-theme="light"] .stat-val,
html[data-theme="light"] .assigned-preview-count {
    color: var(--accent) !important;
}

html[data-theme="light"] .content-section h2,
html[data-theme="light"] .recent-scores h3 {
    color: var(--text-strong);
    border-bottom-color: color-mix(in srgb, var(--text) 15%, transparent);
}

html[data-theme="light"] .feature-card h3 {
    color: var(--text-strong);
}

html[data-theme="light"] .puzzle-type,
html[data-theme="light"] .status-badge,
html[data-theme="light"] .mode-badge,
html[data-theme="light"] .badge {
    background: rgba(253, 251, 249, 0.9) !important;
    border-color: color-mix(in srgb, var(--text) 16%, transparent) !important;
    color: var(--text) !important;
}

/* Filter toggles → neutral ghost chip */
html[data-theme="light"] .filter-btn {
    background: rgba(253, 251, 249, 0.9) !important;
    border-color: color-mix(in srgb, var(--text) 20%, transparent) !important;
    color: var(--text) !important;
}
html[data-theme="light"] .filter-btn:hover {
    border-color: color-mix(in srgb, var(--accent) 50%, transparent) !important;
    color: var(--accent) !important;
}

/* Primary buttons → Deep Burgundy */
html[data-theme="light"] .button,
html[data-theme="light"] .btn,
html[data-theme="light"] .login-button,
html[data-theme="light"] .register-button,
html[data-theme="light"] .try-again-button,
html[data-theme="light"] .action-button,
html[data-theme="light"] .cta-button,
html[data-theme="light"] .template-action {
    background: var(--accent) !important;
    border-color: var(--accent-hover) !important;
    color: #ffffff !important;
}
html[data-theme="light"] .button:hover,
html[data-theme="light"] .btn:hover,
html[data-theme="light"] .login-button:hover,
html[data-theme="light"] .register-button:hover,
html[data-theme="light"] .try-again-button:hover,
html[data-theme="light"] .action-button:hover,
html[data-theme="light"] .cta-button:hover,
html[data-theme="light"] .template-action:hover {
    background: var(--accent-hover) !important;
    border-color: var(--danger) !important;
    color: #ffffff !important;
}

/* Secondary buttons → Sage Green */
html[data-theme="light"] .btn-secondary,
html[data-theme="light"] .action-button.remove,
html[data-theme="light"] .template-action.secondary,
html[data-theme="light"] .btn-sm-edit,
html[data-theme="light"] .btn-disabled {
    background: var(--cat-spatial) !important;
    border-color: var(--cat-spatial) !important;
    color: #ffffff !important;
}

/* Danger buttons → Alert Red */
html[data-theme="light"] .btn-danger {
    background: var(--danger) !important;
    border-color: var(--danger) !important;
    color: #ffffff !important;
}

html[data-theme="light"] .message.error {
    color: var(--danger) !important;
}

html[data-theme="light"] .message.success {
    color: var(--ok) !important;
}

html[data-theme="light"] .error-message {
    color: var(--danger) !important;
}

html[data-theme="light"] .stat-card,
html[data-theme="light"] .achievement-card,
html[data-theme="light"] .puzzle-card,
html[data-theme="light"] .activity-item,
html[data-theme="light"] .user-rank-item,
html[data-theme="light"] .assigned-preview-item,
html[data-theme="light"] .puzzle-option,
html[data-theme="light"] .chip,
html[data-theme="light"] .assigned-chip {
    border-color: color-mix(in srgb, var(--text) 14%, transparent) !important;
    box-shadow: 0 8px 16px color-mix(in srgb, var(--text) 8%, transparent);
}

html[data-theme="light"] .feature-card:hover,
html[data-theme="light"] .stat-card:hover,
html[data-theme="light"] .competition-card:hover,
html[data-theme="light"] .puzzle-card:hover {
    box-shadow: 0 20px 36px color-mix(in srgb, var(--text) 14%, transparent);
    border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}

html[data-theme="light"] table th,
html[data-theme="light"] table td {
    border-bottom-color: color-mix(in srgb, var(--text) 12%, transparent) !important;
}

/* The `html[data-theme="light"] a { color: var(--accent) }` rule that stood here
   has been removed. At specificity (0,1,1) it outranked every component rule
   that styles an anchor as a button, so `.article-cta__btn` in blog.css — which
   sets `color: #fff` at (0,1,0) — lost, and "Try this puzzle" rendered petrol
   text on the brick background the same rule declares. Measured as a WCAG
   contrast failure by Lighthouse on every article page.
   Link colour is already owned by tokens.css (`a { color: var(--link) }`), which
   is a plain (0,0,1) rule and correctly yields to component styles. */

html[data-theme="light"] .tagline,
html[data-theme="light"] .form-hint {
    color: var(--text-muted) !important;
}

* {
    box-sizing: border-box;
}

html,
body {
    min-height: 100%;
}

body {
    margin: 0 !important;
    padding-top: 0;
    padding-right: 0;
    padding-bottom: 44px !important;
    padding-left: 0;
    font-family: var(--font-body) !important;
    color: var(--text);
    background-color: var(--bg-0);
    background-image: none;
}

main,
.competitions-container,
.leaderboard-container,
.about-container,
.admin-container,
.wrap {
    width: min(1200px, calc(100% - 2.5rem));
    margin-left: auto;
    margin-right: auto;
}

h1,
h2,
h3,
h4 {
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: -0.01em;
}

a {
    color: var(--brand-2);
}

/* Shared raised panel surface */
.intro,
.login-card,
.register-card,
.error-card,
.content-section,
.filters-section,
.leaderboard-table,
.recent-scores,
.not-logged-card,
.stats-section,
.achievements-section,
.recent-activity,
.saved-puzzles,
.admin-section,
.page-header,
.competition-card,
.panel,
.form-container {
    background: var(--surface-grad), var(--panel) !important;
    border: 1px solid var(--line) !important;
    border-radius: var(--radius) !important;
    box-shadow: var(--shadow-lg), var(--edge-glow) !important;
    -webkit-backdrop-filter: blur(9px) saturate(115%);
    backdrop-filter: blur(9px) saturate(115%);
}

/* Centred, fixed-width auth cards. `.not-logged-card` was in this group and does
   not belong here: it is used in exactly two places — leaderboard.php:58 and
   competitions.php:53 — and both are full-width page sections, not centred forms.
   The 480px auth treatment made the leaderboard's "Welcome to the Leaderboard"
   section 480px wide between two 1160px siblings, which read as a mistake. It also
   silently beat `.competition-gate { max-width: 62ch }`, since that has no
   `!important` and this does. */
.intro,
.login-card,
.register-card,
.error-card {
    width: min(480px, calc(100% - 2rem)) !important;
    margin: 2.2rem auto !important;
    padding: 2rem !important;
}

/* Same card styling, full content width, for a page-level section.
   Alignment is centred to match the page header above it and the two teaser
   sections below it. Measured before: .not-logged-card was text-align:start while
   .teaser-section (both of them) and .leaderboard-header were text-align:center —
   three peer blocks on one page disagreeing about where their text sits. */
.not-logged-card {
    width: 100% !important;
    margin: 2.2rem 0 !important;
    padding: 2rem !important;
    text-align: center;
}
.not-logged-card h2,
.not-logged-card p {
    text-align: center;
}

.login-card h1,
.register-card h1,
.error-card h1,
.not-logged-card h1,
.leaderboard-header h1,
.page-header h1,
.hero h1 {
    margin: 0 0 0.85rem;
    color: var(--text) !important;
    font-weight: 800;
    line-height: 1.1;
    /* Gradient-clipped text removed: two of the four stops were
       near-white, so these headings turned invisible on the light
       parchment surface, and "gradient text" is exactly the generic
       tell the redesign brief asked to avoid. Solid ink is legible in
       both themes. */
    color: var(--text-strong);
}

.tagline,
.page-header p,
.leaderboard-header p,
.register-link,
.login-link,
.score-details,
.competition-description,
.content-section p,
.stat-label,
.hint {
    color: var(--text-muted) !important;
}

.form-group label,
.filter-group label,
.form-label {
    color: var(--text) !important;
    font-weight: 600 !important;
}

.form-group input,
.form-group select,
.form-group textarea,
.form-input,
input[type='text'],
input[type='password'],
input[type='email'],
input[type='number'],
input[type='datetime-local'],
select,
textarea {
    width: 100%;
    border-radius: 12px !important;
    border: 1px solid rgba(104, 188, 226, 0.4) !important;
    background: rgba(10, 18, 24, 0.82) !important;
    color: var(--text) !important;
    padding: 0.74rem 0.9rem !important;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.form-hint {
    display: block;
    margin-top: 6px;
    font-size: 0.82rem;
    color: var(--text-muted);
    line-height: 1.4;
}

.username-feedback,
.password-feedback {
    display: block;
    margin-top: 6px;
    font-size: 0.82rem;
    line-height: 1.4;
    color: var(--text-muted);
}
.username-feedback[data-state="checking"] { color: var(--text-muted); }
.username-feedback[data-state="available"],
.password-feedback[data-state="ok"] { color: var(--ok); font-weight: 600; }
.username-feedback[data-state="taken"],
.username-feedback[data-state="invalid"],
.username-feedback[data-state="error"],
.password-feedback[data-state="short"],
.password-feedback[data-state="long"],
.password-feedback[data-state="weak"],
.password-feedback[data-state="error"] { color: var(--danger); font-weight: 600; }

.button,
.btn,
.login-button,
.register-button,
.try-again-button,
.action-button,
.cta-button,
.filter-btn,
.template-action {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid transparent !important;
    border-radius: var(--radius-sm) !important;
    color: var(--accent-contrast) !important;
    font-weight: 600 !important;
    /* Was a 2016-era orange gradient (linear-gradient(120deg,var(--accent),var(--accent),var(--accent-hover)))
       painted on EVERY button in the app, which fought the palette wherever it
       appeared — the cookie dialog, puzzle controls, modals. Actions use the accent. */
    background: var(--accent) !important;
    box-shadow: var(--shadow-md) !important;
    transition: transform var(--dur-fast) var(--ease-out),
                background-color var(--dur-fast) linear,
                box-shadow var(--dur-fast) linear;
    text-decoration: none;
}

button {
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    color: var(--accent-contrast);
    font-weight: 600;
    background: var(--accent);
    box-shadow: var(--shadow-md);
    transition: transform var(--dur-fast) var(--ease-out),
                background-color var(--dur-fast) linear,
                box-shadow var(--dur-fast) linear;
    text-decoration: none;
}

.button:hover,
.btn:hover,
.login-button:hover,
.register-button:hover,
.try-again-button:hover,
.action-button:hover,
.cta-button:hover,
.filter-btn:hover,
.template-action:hover,
button:hover {
    transform: translateY(-1px);
    filter: brightness(1.07);
}

.btn-danger,
.message.error {
    /* Was `--danger` ink on a `--danger` tint. The light-theme override below has
       always been a solid danger fill with white ink, so only the base — which is
       what DARK inherits — was dark-on-dark: #E8705C on the 40% tint composites to
       roughly #6C403A, about 2.84:1. The surface carries the meaning; the label
       needs ordinary contrast ink. Now 6.85:1 light and 5.89:1 dark. */
    background: var(--danger) !important;
    border-color: var(--danger) !important;
    color: #ffffff !important;
}
html[data-theme="dark"] .btn-danger,
html[data-theme="dark"] .message.error {
    color: var(--bg-0) !important;
}

.message.success {
    background: linear-gradient(125deg, color-mix(in srgb, var(--ok) 22%, transparent), rgba(35, 96, 72, 0.36)) !important;
    border-color: color-mix(in srgb, var(--ok) 40%, transparent) !important;
    color: #d5ffe8 !important;
}

.error-message {
    background: color-mix(in srgb, var(--danger) 16%, transparent) !important;
    border-left: 4px solid var(--danger) !important;
    color: #ffdbe0 !important;
    border-radius: 10px !important;
}

table {
    width: 100%;
    border-collapse: collapse;
    background: transparent;
}

th,
td {
    border-bottom: 1px solid color-mix(in srgb, var(--accent) 20%, transparent) !important;
    color: var(--text) !important;
}

th {
    color: var(--text-muted) !important;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-size: 0.78rem;
}

.stat-card,
.achievement-card,
.puzzle-card,
.activity-item,
.user-rank-item,
.assigned-preview-item,
.puzzle-option,
.chip,
.assigned-chip {
    background: var(--panel-soft) !important;
    border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent) !important;
    border-radius: 12px !important;
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}

.feature-card {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.feature-card:hover,
.stat-card:hover,
.competition-card:hover,
.puzzle-card:hover {
    transform: translateY(-4px);
    box-shadow: 0 20px 36px rgba(0, 0, 0, 0.35);
    border-color: color-mix(in srgb, var(--accent) 45%, transparent);
}

.not-logged-container {
    min-height: 60vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
}

.hero {
    text-align: center;
    margin: 1.4rem 0 2rem;
    padding: 1.6rem 1.5rem;
}

.hero h1,
.about-container > .hero h1 {
    margin: 0 0 0.7rem;
    font-weight: 800;
    line-height: 1.1;
    /* Gradient-clipped text removed: two of the four stops were
       near-white, so these headings turned invisible on the light
       parchment surface, and "gradient text" is exactly the generic
       tell the redesign brief asked to avoid. Solid ink is legible in
       both themes. */
    color: var(--text-strong);
}

.hero .tagline {
    margin: 0;
    font-size: 1.1rem;
    color: var(--text-muted);
}

.content-section h2 {
    color: var(--text);
    border-bottom: 1px solid color-mix(in srgb, var(--accent) 35%, transparent);
    padding-bottom: 0.45rem;
    margin: 0 0 0.9rem;
    display: flex;
    align-items: center;
    gap: 0.55rem;
}

.features-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
    margin-top: 1.1rem;
}

.feature-card {
    padding: 1.4rem 1.2rem;
    text-align: center;
    background: var(--panel-soft);
    border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
    border-radius: 12px;
    transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.feature-icon {
    font-size: 2.2rem;
    line-height: 1;
    margin-bottom: 0.6rem;
    display: inline-block;
}

.feature-card h3 {
    margin: 0 0 0.5rem;
    color: var(--text-strong);
}

.feature-card p {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.92rem;
    line-height: 1.55;
}

/* CTA links inside feature cards (e.g. the Legal & Policies grid on About). */
.feature-card p + p {
    margin-top: 0.6rem;
}

.feature-card a {
    color: var(--brand-2, var(--accent));
    font-weight: 700;
    text-decoration: none;
    transition: color 0.18s ease;
}

.feature-card a:hover {
    color: #d9f6ff;
    text-decoration: underline;
}

.puzzle-types {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    justify-content: center;
}

.filter-form {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.puzzle-type,
.status-badge,
.mode-badge,
.badge {
    border-radius: 999px !important;
    border: 1px solid color-mix(in srgb, var(--accent) 35%, transparent) !important;
    background: color-mix(in srgb, var(--bg-0) 72%, transparent) !important;
    color: var(--text) !important;
}

/* === About page: stats strip, puzzle shelf and how-it-works ===
   Reuses the raised .content-section surface and chip styling already
   defined above; tokens keep everything working in light + dark themes. */

/* Stats brag-row under the hero */
.about-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    justify-content: center;
    margin: 0 0 1.6rem;
}

.about-stat {
    flex: 1 1 150px;
    min-width: 140px;
    text-align: center;
    padding: 1rem 0.9rem;
    background: var(--panel-soft);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-md), var(--edge-glow);
}

.about-stat__num {
    display: block;
    font-family: var(--font-display);
    font-size: 1.7rem;
    font-weight: 800;
    line-height: 1.1;
    /* Gradient-clipped text removed: two of the four stops were
       near-white, so these headings turned invisible on the light
       parchment surface, and "gradient text" is exactly the generic
       tell the redesign brief asked to avoid. Solid ink is legible in
       both themes. */
    color: var(--text-strong);
}

.about-stat__label {
    display: block;
    margin-top: 0.3rem;
    font-size: 0.85rem;
    color: var(--text-muted);
}

html[data-theme='light'] .about-stat__num {
    /* Gradient-clipped text removed: two of the four stops were
       near-white, so these headings turned invisible on the light
       parchment surface, and "gradient text" is exactly the generic
       tell the redesign brief asked to avoid. Solid ink is legible in
       both themes. */
    color: var(--text-strong);
}

/* Puzzle shelf: two labeled grids of named chips */
.puzzle-catalog {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 1rem;
    margin-top: 1.1rem;
}

.puzzle-catalog__group {
    padding: 1.1rem 1rem;
    background: var(--panel-soft);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

.puzzle-catalog__title {
    margin: 0 0 0.8rem;
    font-size: 1.02rem;
    color: var(--text);
    display: flex;
    align-items: center;
    gap: 0.45rem;
}

html[data-theme='light'] .puzzle-catalog__title {
    color: var(--text);
}

.puzzle-catalog__grid {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Give the catalog chips a touch more breathing room than bare badges */
.puzzle-catalog .puzzle-type {
    padding: 0.4rem 0.85rem !important;
    font-size: 0.9rem;
    font-weight: 600;
    transition: transform 0.18s ease, border-color 0.18s ease;
}

.puzzle-catalog .puzzle-type:hover {
    transform: translateY(-2px);
    border-color: color-mix(in srgb, var(--accent) 60%, transparent) !important;
}

/* How it works: numbered 3-up step row */
.how-it-works {
    list-style: none;
    margin: 1.1rem 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 1rem;
    counter-reset: step;
}

.how-it-works__step {
    position: relative;
    padding: 1.5rem 1.2rem 1.2rem;
    background: var(--panel-soft);
    border: 1px solid var(--line);
    border-radius: var(--radius);
}

.how-it-works__num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.1rem;
    height: 2.1rem;
    margin-bottom: 0.7rem;
    border-radius: 999px;
    font-family: var(--font-display);
    font-weight: 800;
    color: #0d222d;
    background: linear-gradient(135deg, var(--accent), var(--accent));
}

.how-it-works__step h3 {
    margin: 0 0 0.45rem;
    color: var(--text-strong);
    font-size: 1.05rem;
}

html[data-theme='light'] .how-it-works__step h3 {
    color: var(--text);
}

.how-it-works__step p {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.92rem;
    line-height: 1.55;
}

/* === About page visual enhancements ===
   Adds rhythm, visual hierarchy, and decorative accents so the page
   feels crafted rather than a flat stack of panels. */

/* Hero: decorative watermark and extra breathing room */
.about-container > .hero {
    position: relative;
    overflow: hidden;
    padding: 2.2rem 1.5rem 2.4rem;
    margin: 1.2rem 0 2.4rem;
}

.about-container > .hero::before {
    content: '';
    position: absolute;
    top: -3rem;
    right: -2rem;
    width: 14rem;
    height: 14rem;
    background: radial-gradient(circle, color-mix(in srgb, var(--accent) 9%, transparent) 0%, transparent 70%);
    border-radius: 50%;
    pointer-events: none;
}

.about-container > .hero::after {
    content: '';
    position: absolute;
    bottom: -2.5rem;
    left: -2rem;
    width: 11rem;
    height: 11rem;
    background: radial-gradient(circle, color-mix(in srgb, var(--accent) 9%, transparent) 0%, transparent 70%);
    border-radius: 50%;
    pointer-events: none;
}

/* Stats strip: gradient top bars, hover lift */
.about-stat {
    position: relative;
    overflow: hidden;
    transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}

.about-stat::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--brand), var(--brand-2));
    border-radius: var(--radius) var(--radius) 0 0;
}

.about-stat:hover {
    transform: translateY(-2px);
    box-shadow: 0 14px 28px rgba(0, 0, 0, 0.25);
    border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}

/* Content sections: alternating left-accent borders for visual rhythm.
   Targets content-sections inside the about container, skipping .hero
   and .about-stats (which are not .content-section). */
.about-container > .content-section {
    margin-bottom: 1.6rem;
    padding: 1.6rem 1.6rem 1.6rem 1.3rem;
    transition: border-color 0.2s ease;
    position: relative;
}

/* First, third, fifth content sections → orange accent */
.about-container > .content-section:nth-of-type(3),
.about-container > .content-section:nth-of-type(5) {
    border-left: 4px solid color-mix(in srgb, var(--accent) 35%, transparent);
}

/* Second, fourth, sixth → cyan accent */
.about-container > .content-section:nth-of-type(4),
.about-container > .content-section:nth-of-type(6) {
    border-left: 4px solid color-mix(in srgb, var(--accent) 35%, transparent);
}

/* Puzzle shelf: left-border accents per group + hover */
.puzzle-catalog__group {
    position: relative;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.puzzle-catalog__group:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.25);
}

.puzzle-catalog__group:first-child {
    border-left: 3px solid color-mix(in srgb, var(--accent) 40%, transparent);
}

.puzzle-catalog__group:last-child {
    border-left: 3px solid color-mix(in srgb, var(--accent) 40%, transparent);
}

/* How it works: connecting gradient line + bigger numbers + hover */
.how-it-works {
    position: relative;
}

.how-it-works::before {
    content: '';
    position: absolute;
    top: 2.8rem;
    left: 12%;
    right: 12%;
    height: 2px;
    background: linear-gradient(
        90deg,
        color-mix(in srgb, var(--accent) 20%, transparent),
        color-mix(in srgb, var(--accent) 45%, transparent) 50%,
        color-mix(in srgb, var(--accent) 20%, transparent)
    );
    border-radius: 1px;
    z-index: 0;
    pointer-events: none;
}

.how-it-works__step {
    position: relative;
    z-index: 1;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.how-it-works__step:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 24px rgba(0, 0, 0, 0.25);
}

.how-it-works__num {
    width: 2.5rem;
    height: 2.5rem;
    font-size: 1.1rem;
    box-shadow: 0 3px 10px color-mix(in srgb, var(--accent) 30%, transparent);
}

/* Feature cards: top gradient bar + circular icon backgrounds */
.feature-card {
    position: relative;
    padding-top: 2rem;
}

.feature-card::before {
    content: '';
    position: absolute;
    top: 0;
    left: 1rem;
    right: 1rem;
    height: 3px;
    background: linear-gradient(90deg, var(--brand), var(--brand-2));
    border-radius: 2px;
}

.feature-icon {
    width: 3rem;
    height: 3rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 18%, transparent), color-mix(in srgb, var(--accent) 15%, transparent));
    border-radius: 50%;
    font-size: 1.5rem;
    line-height: 1;
}

/* Motto section: highlighted callout with warm gradient glow */
.content-section--motto {
    border-left: 4px solid var(--brand) !important;
    background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 9%, transparent), color-mix(in srgb, var(--accent) 4%, transparent) 55%, rgba(0, 0, 0, 0.06)),
        var(--surface-grad), var(--panel) !important;
    margin-bottom: 1.6rem;
}

.content-section--motto h2 {
    color: var(--accent);
}

/* Legal section: subtle top-accent on feature cards */
.content-section--legal .feature-card::before {
    background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 50%, transparent), color-mix(in srgb, var(--accent) 50%, transparent));
}

/* Responsive: hide how-it-works line on narrow screens */
@media (max-width: 768px) {
    .how-it-works::before {
        display: none;
    }

    .about-container > .hero {
        padding: 1.5rem 1rem 1.8rem;
    }

    .feature-icon {
        width: 2.5rem;
        height: 2.5rem;
        font-size: 1.3rem;
    }
}

/* Light-mode overrides for about page enhancements */
html[data-theme='light'] .about-stat::before {
    background: linear-gradient(90deg, var(--accent), var(--cat-spatial));
}

html[data-theme='light'] .about-stat:hover {
    box-shadow: 0 14px 28px color-mix(in srgb, var(--text) 12%, transparent);
    border-color: color-mix(in srgb, var(--accent) 30%, transparent);
}

html[data-theme='light'] .about-container > .hero::before {
    background: radial-gradient(circle, color-mix(in srgb, var(--accent) 6%, transparent) 0%, transparent 70%);
}

html[data-theme='light'] .about-container > .hero::after {
    background: radial-gradient(circle, color-mix(in srgb, var(--ok) 6%, transparent) 0%, transparent 70%);
}

html[data-theme='light'] .content-section--motto {
    background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 6%, transparent), color-mix(in srgb, var(--ok) 3%, transparent) 55%, rgba(0, 0, 0, 0.01)),
        var(--surface-grad), var(--panel) !important;
}

html[data-theme='light'] .content-section--motto h2 {
    color: var(--accent);
}

html[data-theme='light'] .feature-icon {
    background: linear-gradient(135deg, color-mix(in srgb, var(--accent) 10%, transparent), color-mix(in srgb, var(--ok) 10%, transparent));
}

html[data-theme='light'] .puzzle-catalog__group:first-child {
    border-left-color: color-mix(in srgb, var(--accent) 35%, transparent);
}

html[data-theme='light'] .puzzle-catalog__group:last-child {
    border-left-color: color-mix(in srgb, var(--ok) 35%, transparent);
}

html[data-theme='light'] .how-it-works__num {
    box-shadow: 0 3px 10px color-mix(in srgb, var(--accent) 20%, transparent);
}

html[data-theme='light'] .about-container > .content-section:nth-of-type(3),
html[data-theme='light'] .about-container > .content-section:nth-of-type(5) {
    border-left-color: color-mix(in srgb, var(--accent) 30%, transparent);
}

html[data-theme='light'] .about-container > .content-section:nth-of-type(4),
html[data-theme='light'] .about-container > .content-section:nth-of-type(6) {
    border-left-color: color-mix(in srgb, var(--ok) 30%, transparent);
}

/* === Legal pages (Privacy Policy / Terms of Service) and shared footer ===
   Reuse the raised .content-section panel surface and add readable prose
   styling that works for long-form policy text. */
.legal-container {
    max-width: 860px;
    padding-bottom: 2rem;
}

.legal-meta {
    margin: 0.4rem 0 0;
    font-size: 0.85rem;
    color: var(--text-muted);
    font-style: italic;
}

.legal-intro p {
    font-size: 1.02rem;
    line-height: 1.65;
}

/* Highlighted call-out used for the Cookies/AdSense and Advertising sections. */
.legal-highlight {
    border-left: 3px solid var(--brand-2, #51d6ff) !important;
}

.legal-list {
    margin: 0.6rem 0 0;
    padding-left: 1.25rem;
    display: grid;
    gap: 0.5rem;
    color: var(--text-muted);
    line-height: 1.6;
}

.legal-list li::marker {
    color: var(--brand-2, var(--accent));
}

.legal-list strong {
    color: var(--text, #eaf4fa);
    font-weight: 700;
}

.legal-note {
    margin-top: 0.9rem;
    padding: 0.6rem 0.85rem;
    border-radius: 10px;
    background: rgba(255, 214, 102, 0.08);
    border: 1px solid rgba(255, 214, 102, 0.28);
    color: #ffe6a3;
    font-size: 0.85rem;
    line-height: 1.5;
}

html[data-theme='light'] .legal-note {
    /* The `!important` is load-bearing, and its absence is why this rule — and the
       #9a7a2e it replaced — never did anything. `.legal-note` is a <p> inside
       `.content-section`, so the grouped rule
           .content-section p { color: var(--text-muted) !important; }
       matched it and won. The note therefore rendered in muted grey on its amber
       tint: contrast 5.67:1, which passes, so nothing was broken — but the amber
       callout that was intended had never appeared.
       With the rule effective, --warn on the tint measures 5.93:1. */
    background: color-mix(in srgb, var(--warn) 12%, transparent);
    border-color: color-mix(in srgb, var(--warn) 35%, transparent);
    color: var(--warn) !important;
}

.legal-contact {
    margin: 0.3rem 0 0;
    font-size: 1.05rem;
    font-weight: 700;
}

.legal-contact a {
    color: var(--brand-2, var(--accent));
    text-decoration: none;
    border-bottom: 1px dashed currentColor;
}

.legal-contact a:hover {
    /* Was #d9f6ff, another un-overridden pale blue: ~1.2:1 on the light panel,
       so the link vanished exactly when hovered. */
    color: var(--accent-hover);
}

/* Inline code used for cookie flags etc. */
.legal-container code {
    
    /* --font-mono, not --font-family-mono: the latter is defined only by the
       per-game sheets, which are not loaded on every page. The previous
       `var(--font-family-mono, ui-monospace, monospace)` therefore resolved to a
       bare system stack here and skipped the metric-matched fallback, so this
       reflowed when JetBrains Mono swapped in — measured as the +97px growth of
       .puzzle-help that produced CLS 0.144 on /play/wordsearch. */
    font-family: var(--font-mono);
    font-size: 0.85em;
    padding: 1px 6px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--accent) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
    /* Was var(--text) — a pale blue with no light-theme override, sitting on a 12%
       accent tint. Measured on /privacy: 1.13:1, so every <code> token on the
       privacy and cookie pages was effectively invisible in light theme. The
       accent reads on its own tint in both themes (7.77:1 light, 6.80:1 dark). */
    color: var(--accent);
}

/* Link row at the bottom of each legal page */
.legal-links {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    margin-top: 2rem;
    font-weight: 700;
}

/* WHY THIS EXISTS — a bare `nav a` rule is painting these links white.
   -------------------------------------------------------------------------
   See the `nav` / `nav a` rules further up this file. They were written for the
   ORIGINAL site header — a centred flex row of white links on a dark bar — but
   they are element selectors, so they still apply to every <nav> in the app.
   At (0,0,2) `nav a` outranks the `a` rule at (0,0,1), so on the legal pages the
   `.legal-links` nav inherited `color: #fff` on a cream page background: white
   on #F4F1E9, a contrast ratio of about 1.06:1. The links were not merely low
   contrast, they were invisible. Lighthouse flagged exactly four nodes on
   /privacy — the four links in this nav.

   This rule is (0,1,1), so it outranks `nav a` without touching the legacy rules
   themselves. It is deliberately the narrow fix: `nav` and `nav a` are still the
   only styling `.account-tabs` has anywhere in the codebase, so deleting them
   would restyle the account page, which is outside this change and cannot be
   verified without a signed-in session. The proper fix is to give `.account-tabs`
   its own rules and then delete the bare element selectors; until then this stays
   scoped to the nav that was actually broken. */
.legal-links a {
    margin: 0;
    color: var(--accent);
    text-decoration: none;
    font-weight: 700;
}
.legal-links a:hover {
    color: var(--accent-hover);
    text-decoration: underline;
}

/* Shared site footer (About / Privacy / Terms) */
/* The footer is site chrome and now lives in public/css/chrome.css, so that it
   is styled on every page. It used to be defined here, which meant /3d — which
   loads index3D/styles.css and landing-copy.css but NOT this file — rendered an
   unstyled footer. The old rules also used a `backdrop-filter` glass panel, an
   off-palette taupe gradient, and a broken `.footer-links a:hover` selector:
   the space before `hover` makes it an invalid selector, so the hover state
   silently never applied. */

/* The cookie consent bar is site chrome and now lives in public/css/chrome.css.
   It used to be defined here, which meant /3d and every puzzle page — none of
   which load this file — rendered the consent bar completely unstyled:
   `position: static`, no card background, no border, sitting in normal flow at
   the end of the document. That also produced a 0.059 CLS on /3d, because the
   unstyled block occupied real layout space when the JS unhid it. */

/* Keep puzzle pages usable after global theme update */
.resizable-div,
.cipher-cell,
.cell,
.sudoku-cell,
.number-button,
.tab-button,
.puzzle-container {
    color: #111;
}

@media (max-width: 900px) {
    .competitions-container,
    .leaderboard-container,
    .about-container,
    .admin-container,
    .wrap,
    main {
        width: calc(100% - 1.2rem);
    }

    .filters-section,
    .competition-actions,
    .stats-grid,
    .leaderboard-stats,
    .user-rankings,
    .form-grid {
        gap: 0.7rem !important;
    }

    /* About page: let the new grids collapse comfortably on phones */
    .about-stats,
    .puzzle-catalog,
    .how-it-works {
        gap: 0.7rem;
    }

    .about-stat {
        flex: 1 1 calc(50% - 0.7rem);
        min-width: 0;
    }
}

@media (max-width: 360px) {
    main,
    .competitions-container,
    .leaderboard-container,
    .about-container,
    .admin-container,
    .wrap {
        width: calc(100% - 0.75rem);
    }

    th, td {
        font-size: 0.7rem !important;
        padding: 0.3rem 0.35rem !important;
    }

    .features-grid {
        grid-template-columns: 1fr;
    }

    .login-card,
    .register-card,
    .error-card {
        width: calc(100% - 1rem) !important;
        padding: 1rem !important;
    }

    .login-card h1,
    .register-card h1,
    .error-card h1 {
        font-size: 1.4rem;
    }
}

@media print {
    .no-print,
    .template-actions,
    .site-header {
        display: none !important;
    }

    body {
        color: #000;
        background: #fff;
    }
}

/* =========================================================================
   CROSSWORD PAPER — template re-skin (appended; wins by source order +
   !important). Recolors the legacy orange/cyan brand palette used across the
   auth, leaderboard, competitions, account, about & legal pages to the new
   vermilion + paper/ink system. Presentational only — no selectors or
   layout changed in the rules above.
   ========================================================================= */

/* Gradient-clipped headings → solid ink/cream */
.login-card h1, .register-card h1, .error-card h1, .not-logged-card h1,
.leaderboard-header h1, .page-header h1, .hero h1,
.about-container > .hero h1 {
    background: none !important;
    -webkit-background-clip: border-box !important;
    background-clip: border-box !important;
    -webkit-text-fill-color: currentColor !important;
    color: var(--text) !important;
}
.about-stat__num {
    background: none !important;
    -webkit-background-clip: border-box !important;
    background-clip: border-box !important;
    -webkit-text-fill-color: currentColor !important;
    color: var(--accent) !important;
    font-family: var(--font-display) !important;
}
html[data-theme='light'] .about-stat__num {
    background: none !important;
    -webkit-text-fill-color: currentColor !important;
    color: var(--accent) !important;
}

/* Primary buttons → solid accent.
   The `!important`s are gone from here and from the bare `button {}` rule near
   the top of this file. Together they were a second, later copy of the same six
   declarations, and between them they overrode every component that had been
   written to look like something else — see the note on the `.cookie-modal__switch`
   fix in chrome.css, where the consent switches' OFF state and ON state rendered
   identically because of it. The grouped class selectors still win on source
   order; only the bare `button` in this list gave up its override, which is
   exactly what lets a component opt out. */
.button, .btn, .login-button, .register-button, .try-again-button,
.action-button, .cta-button, .filter-btn, button {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-contrast);
}
.button:hover, .btn:hover, .login-button:hover, .register-button:hover,
.try-again-button:hover, .action-button:hover, .cta-button:hover,
.filter-btn:hover, button:hover {
    filter: brightness(1.05);
}

/* Secondary / quiet buttons → outline brand-2 */
.btn-secondary, .action-button.remove, .template-action.secondary,
.btn-sm-edit, .btn-disabled {
    background: transparent !important;
    border-color: var(--line) !important;
    color: var(--brand-2) !important;
}

/* Forms → hairline border, panel bg, accent focus ring */
.form-group label, .filter-group label, .form-label {
    color: var(--text) !important;
}
.form-group input, .form-group select, .form-group textarea,
.form-input, input[type='text'], input[type='password'], input[type='email'],
input[type='number'], input[type='datetime-local'], select, textarea {
    border-color: var(--line) !important;
    background: var(--panel) !important;
    color: var(--text) !important;
}
input:focus, select:focus, textarea:focus, .form-input:focus {
    border-color: var(--accent) !important;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent) !important;
    outline: 0 !important;
}

/* Tables */
th { color: var(--text-muted) !important; }
th, td { border-bottom-color: var(--line) !important; }

/* Stat / rank numbers → brand-2 accent */
.stat-number, .rank-number, .stat-value, .stat-val,
.competition-status, .assigned-preview-count, .score-value {
    color: var(--brand-2) !important;
}

/* Badges / chips → neutral surface */
.puzzle-type, .status-badge, .mode-badge, .badge {
    border-color: var(--line) !important;
    background: var(--panel) !important;
    color: var(--text) !important;
}

/* Card surfaces → hairline borders */
.stat-card, .achievement-card, .puzzle-card, .activity-item,
.user-rank-item, .assigned-preview-item, .puzzle-option, .chip,
.assigned-chip, .feature-card {
    border-color: var(--line) !important;
}
.feature-card h3 { color: var(--text) !important; }
.content-section h2 { color: var(--text) !important; border-bottom-color: var(--line) !important; }
.puzzle-catalog__title { color: var(--text) !important; }
.how-it-works__step h3 { color: var(--text) !important; }

/* Hover emphasis → accent border */
.feature-card:hover, .stat-card:hover, .competition-card:hover,
.puzzle-card:hover, .about-stat:hover {
    border-color: var(--accent) !important;
}
.puzzle-catalog .puzzle-type:hover { border-color: var(--accent) !important; }
.feature-card a { color: var(--brand-2) !important; }
.feature-card a:hover { color: var(--accent) !important; }
a { color: var(--brand-2); }
a:hover { color: var(--accent); }

/* How-it-works number badge → vermilion disc; connecting line → hairline */
.how-it-works__num {
    color: var(--accent-contrast) !important;
    background: var(--accent) !important;
    font-family: var(--font-display) !important;
}
.how-it-works::before { background: var(--line) !important; }

/* About decorative blobs → faint accent (was orange/cyan) */
.about-container > .hero::before {
    background: radial-gradient(circle, color-mix(in srgb, var(--accent) 12%, transparent) 0%, transparent 70%) !important;
}
.about-container > .hero::after {
    background: radial-gradient(circle, color-mix(in srgb, var(--brand-2) 12%, transparent) 0%, transparent 70%) !important;
}

/* Alternating section + catalog accent borders → accent / brand-2 */
.about-container > .content-section:nth-of-type(3),
.about-container > .content-section:nth-of-type(5) { border-left-color: var(--accent) !important; }
.about-container > .content-section:nth-of-type(4),
.about-container > .content-section:nth-of-type(6) { border-left-color: var(--brand-2) !important; }
.puzzle-catalog__group:first-child { border-left-color: var(--accent) !important; }
.puzzle-catalog__group:last-child { border-left-color: var(--brand-2) !important; }

/* Call to action in the About hero.
   -------------------------------------------------------------------------
   Measured at 1440x900, this page's first interactive element used to be the
   Privacy Policy link 2259px down the document — a visitor who read the whole
   first screen had nothing to do and nowhere to go. An About page is still a
   landing page; it has to offer the next step.

   Deliberately self-contained rather than reusing `.big-btn`. That class is
   defined in css/index2D/styles.css, which /about does not load, so borrowing it
   produced a 19px-tall unstyled link — a component is only reusable on pages that
   load the sheet defining it. This uses only tokens, which every page has. */
.hero-cta {
    margin: 1.75rem 0 0;
    display: flex;
    justify-content: center;
}
.hero-cta__btn {
    display: inline-flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    max-width: 30rem;
    padding: 16px 20px;
    border: 1.5px solid var(--accent);
    border-radius: var(--radius);
    background: var(--accent);
    color: var(--accent-contrast);
    text-decoration: none;
    transition: transform var(--dur) var(--ease-out), filter var(--dur) var(--ease-out);
}
.hero-cta__btn:hover {
    transform: translateY(-1px);
    filter: brightness(1.06);
}
.hero-cta__btn:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
}
.hero-cta__icon { display: inline-flex; flex-shrink: 0; }
.hero-cta__icon svg { width: 26px; height: 26px; }
.hero-cta__label {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    text-align: left;
}
.hero-cta__label strong {
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 700;
    line-height: 1.2;
}
.hero-cta__label small {
    font-size: 0.75rem;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    opacity: 0.85;
}
.hero-cta__arrow { margin-left: auto; flex-shrink: 0; }
