/**
 * Suunta.ai Console - Base CSS
 * ============================
 * Reset, layout foundations, and typography
 */

/* ==========================================
   FONTS — Inter Variable, self-hosted (OFL, rsms/inter). Variable wght axis
   100..900 so --font-weight-display:650 + font-optical-sizing:auto keep working.
   Loaded by console + auth (both inherit base.css). family stays 'Inter' so
   variables.css + font-feature-settings (cv11/ss01/ss03/cv02) are unchanged.
   Removes the render-blocking Google Fonts stylesheet from the console FCP path.
   ========================================== */

/* SIIRTYMÄ — Inter ei ole enää ilmeen kirjasin (STYLEGUIDE §6: Schibsted
   Grotesk / Newsreader / IBM Plex Mono, ks. fonts.css). Nämä @font-face-
   säännöt jäävät vain siksi, että ops/tokens.css, legal.css ja brand-kit.css
   viittaavat perheeseen yhä nimellä. Poistetaan MIGRAATIO.md:n vaiheessa 5
   yhdessä niiden viittausten kanssa. */
@font-face {
    font-family: 'Inter';
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url('/static/fonts/InterVariable.woff2') format('woff2');
}

@font-face {
    font-family: 'Inter';
    font-style: italic;
    font-weight: 100 900;
    font-display: swap;
    src: url('/static/fonts/InterVariable-Italic.woff2') format('woff2');
}

/* ==========================================
   CROSS-DOCUMENT VIEW TRANSITIONS
   Smooth crossfade between pages — no white flash.
   Chrome 126+, progressive enhancement.
   ========================================== */

@view-transition {
    navigation: auto;
}

/* Fast crossfade: old page fades out, new page fades in */
::view-transition-old(root) {
    animation: suunta-fade-out 0.12s ease-out both;
}
::view-transition-new(root) {
    animation: suunta-fade-in 0.14s ease-in both;
}

@keyframes suunta-fade-out {
    from { opacity: 1; }
    to   { opacity: 0; }
}
@keyframes suunta-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
}

/* Keep sidebar/nav stable during transition — only content area animates */
.console-sidebar,
.icon-rail {
    view-transition-name: sidebar;
}
::view-transition-old(sidebar),
::view-transition-new(sidebar) {
    animation: none;
}

/* Respect reduced-motion: skip the crossfade animation so vestibular-sensitive
   users get an instant page swap (no fade), not a moving transition. */
@media (prefers-reduced-motion: reduce) {
    ::view-transition-old(root),
    ::view-transition-new(root) {
        animation: none;
    }
}

/* ==========================================
   NAVIGATION PROGRESS BAR
   Soft emerald glow at top — elegant loading feedback.
   ========================================== */

.nav-progress {
    position: fixed;
    top: 0;
    left: 0;
    width: 0;
    height: 2px;
    background: linear-gradient(90deg, var(--emerald-500), var(--emerald-400, #34d399));
    box-shadow: 0 0 12px rgba(16, 185, 129, 0.5), 0 0 4px rgba(16, 185, 129, 0.3);
    border-radius: 0 1px 1px 0;
    z-index: 99999;
    pointer-events: none;
    opacity: 0;
    transform: scaleX(0);
    transform-origin: left;
}

.nav-progress--active {
    opacity: 1;
    animation: nav-progress-grow 2.5s cubic-bezier(0.25, 0.8, 0.25, 1) forwards;
}

.nav-progress--complete {
    animation: nav-progress-finish 0.35s ease-out forwards;
}

@keyframes nav-progress-grow {
    0%   { transform: scaleX(0); opacity: 0.6; }
    5%   { opacity: 1; }
    15%  { transform: scaleX(0.25); }
    40%  { transform: scaleX(0.55); }
    65%  { transform: scaleX(0.75); }
    100% { transform: scaleX(0.88); }
}

@keyframes nav-progress-finish {
    0%   { opacity: 1; }
    40%  { transform: scaleX(1); opacity: 1; }
    100% { transform: scaleX(1); opacity: 0; }
}

/* ==========================================
   RESET & BOX-SIZING
   ========================================== */

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

/* ==========================================
   [hidden] ON AINA PIILOTETTU
   ==========================================

   Selaimen oma sääntö on `[hidden] { display: none }`, spesifisyys (0,1,0).
   Jokainen komponentti joka asettaa `display: flex/grid/block` luokalleen
   voittaa sen, jolloin `element.hidden = true` ei tee mitään. Mikään ei
   näytä rikkinäiseltä: JS asettaa attribuutin, DOM ottaa sen vastaan, ja
   elementti jää ruudulle.

   Ansa on löydetty ja paikattu käsin **171 kertaa 88 tiedostossa** (mitattu
   27.8.2026). Osa paikkauksista kantaa oman kommenttinsa siitä että sama
   asia keksittiin uudelleen — `components/strategy-connection.css` listaa
   13 valitsinta, `pages/toteutus/toteutus_v5_minimalist_drawer.css` nimeää
   sen «display vs hidden -ansaksi». Tämä sääntö tekee ne tarpeettomiksi;
   niitä ei poisteta tässä, koska poisto on eri päätös kuin lisäys.

   `!important` on välttämätön eikä tyylivalinta: kaskadi on latausjärjestys
   (`app/utils/console_base_bundle.py`), ja `base.css` on kolmas — jokainen
   myöhempi komponenttitiedosto voittaisi tämän ilman sitä.

   TAHALLINEN POIKKEUS kirjoitetaan omalla `!important`illaan korkeammalla
   spesifisyydellä, esim. `.bottom-sheet[hidden] { display: block !important }`
   (0,2,0) — animoituva paneeli tarvitsee laatikon jotta siirtymä toimii.
   Vartija: tests/unit/test_hidden_attribute_wins.py */
[hidden] {
    display: none !important;
}

/* Touch interaction: eliminate tap delay and highlight flash */
button, a, [role="button"], input, select, textarea, label,
.btn, .card, [onclick], [data-action] {
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}

/* Globaali sääntö: lomakekentät perivät sovelluksen fontin (Inter). Ilman tätä
   <textarea> saa selaimen monospace-OLETUKSEN ja <input>/<button> voivat saada
   platform-UI-fontin → tekstikentät + placeholderit renderöityivät väärällä
   fontilla, vastoin tyylikieltä (Inter kaikkialla). <code>/<pre> säilyttää
   monospacen (eri elementti). */
input, textarea, select, button {
    font-family: inherit;
    /* Sama perustelu kuin fontilla, ja sama vika toisessa ominaisuudessa:
       lomake-elementit EIVÄT peri `color`ia, vaan saavat UA:n `buttontext` /
       `fieldtext` -värin. Tummalla `color-scheme`illa se on VALKOINEN.
       Mitattu 24.8.2026: `.mobile-topbar__avatar` laski väriksi #ffffff
       vaikka yksikään sääntö ei aseta sille väriä — se ei näkynyt vain siksi,
       että sen ainoa lapsi asettaa oman värinsä. Mikä tahansa suora teksti
       napissa olisi renderöitynyt väärällä värillä.

       Sama perhe kuin `<button>`in UA-reunassa: se mitä ei aseta, tulee
       selaimelta, ja selaimen oletus ei tunne ilmettä. */
    color: inherit;
}

/* Globaali sääntö: yhdessäkään tekstikentässä ei ole käyttäjän kahvaa
   kokomuokkaukseen. Mitoitus tulee aina komponentista (min-height,
   max-height tai rows-attr) — käyttäjä ei venytä layoutia rikki. */
textarea {
    resize: none;
}

html {
    font-size: 16px;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    /* Background is also set inline on <html> by the base templates'
       theme-init script so overscroll bounce (Safari, macOS) shows the
       correct colour. This CSS declaration is the steady-state value
       once CSS variables resolve. */
    background: var(--color-bg-primary);
    /* Prevent the browser's grey/white overscroll glow from leaking
       through. `contain` still lets scroll chain inside the page. */
    overscroll-behavior-y: contain;
}

html, body {
    margin: 0;
    padding: 0;
    overflow-x: hidden;
    background: var(--color-bg-primary);
    color: var(--color-text-primary);
    font-family: var(--font-family);
    line-height: var(--line-height-normal);

    /* Premium Inter glyph variants applied globally.
       cv11: single-storey 'a' (more humanist);
       ss01: alternate '1' with serif foot (less ambiguous next to 'l', 'I');
       ss03: lowercase 'l' with tail (disambiguates from '1', 'I');
       cv02: open '4' (clearer at small sizes).
       Optical sizing lets Inter Variable adjust contrast for size. */
    font-feature-settings: 'cv11', 'ss01', 'ss03', 'cv02';
    font-optical-sizing: auto;
}

/* ==========================================
   NUMERIC UTILITY
   `tabular-nums` keeps digit widths uniform so live-updating values
   (KPI counters, credit balance, progress %) don't shift the layout.
   ========================================== */

.num,
.tabular {
    font-variant-numeric: tabular-nums;
    font-feature-settings: 'tnum', 'cv11', 'ss01', 'ss03', 'cv02';
}

/* ==========================================
   EYEBROW UTILITY
   Small UPPERCASE label that sits above a heading or section title.
   The pattern was being copy-pasted across dozens of components — this
   utility is the single source of truth.

   Variants:
     .eyebrow            — default label text (muted)
     .eyebrow--muted     — alias for the default (see note at the variant)
     .eyebrow--accent    — emerald accent for callouts / new sections

   Väri on `--text-muted`, ei `--text-tertiary` (vaihdettu 2026-08-17).
   Mitattuna alfa-sekoituksen kanssa oikeaa taustaa vasten:

     --text-secondary  9.88 tumma / 7.31 vaalea   AA ✓
     --text-muted      4.58 tumma / 5.54 vaalea   AA ✓ (juuri)
     --text-tertiary   3.75 tumma / 3.88 vaalea   AA ✗ molemmissa

   Tertiary ei jää AA:n alle vahingossa vaan rakenteesta: AA vaatii 4.5 ja
   muted on 4.58, joten neljännelle tekstitasolle ei ole väliä johon mahtua.
   Tokenia EI siis pidä nostaa — se romahtaisi mutediksi. Se on
   koriste- ja disabled-token, ei tekstiväri. Eyebrow on oikeaa tekstiä
   (usein osion ainoa otsikko), joten se kuuluu mutediin.
   ========================================== */

/* Versaali VAIN monossa (STYLEGUIDE saanto 10), ja pienin sans on 13 px
   (§6.2). `.eyebrow` rikkoi molempia: 12 px sansia VERSAALINA. Se on
   samalla `.ilme .mono`n kaksoiskappale vaaralla kirjasimella — sama koko,
   sama tracking, sama versaali, eri fontti.

   Korjaus on kirjasin, ei koko: mono 12 px on sallittu ja se on se mita
   ilme jo kayttaa marginaaliotsikoihin. Mitattu 29.8.2026: leveys kasvaa
   noin 10 %, eika yksikaan pinta vuoda 390 px:ssa eika 1440 px:ssa. */
.eyebrow {
    font-family: var(--mono);
    font-size: var(--font-size-eyebrow);
    font-weight: 500;
    letter-spacing: var(--tr-mono);
    text-transform: uppercase;
    line-height: var(--leading-snug);
    color: var(--text-muted);
}

/* Tarkoituksellinen alias, ei erottelu — ja se on rehellisempi kuin se mitä
   tässä oli ennen. Variantti osoitti `--text-muted`iin (4.58) samalla kun
   `.eyebrow` oli `--text-tertiary` (3.75): "muted"-niminen luokka oli siis
   perusluokkaa ÄÄNEKKÄÄMPI, päinvastoin kuin nimi lupaa. Kommentti puhui
   40 %:n opacitystä jota se ei käyttänyt.

   Hiljaisemmalle portaalle ei ole tilaa: seuraava askel alaspäin on
   tertiary, joka jää AA:n alle (ks. yllä). Luokka pidetään — sitä käyttää
   32 tiedostoa — mutta se on nyt sama väri, ei hiljaisempi. */
.eyebrow--muted {
    color: var(--text-muted);
}

.eyebrow--accent {
    color: var(--accent-text-emerald, var(--emerald-500));
}

/* ==========================================
   DISPLAY UTILITY
   Apply to any heading or numeric element ≥ 24px that should feel
   premium. Adds a half-weight (650 — between semibold and bold) plus
   tighter tracking and display-tight leading. Inter Variable
   interpolates the half-weight; static fonts will round to 700.

   Use either as `<h1 class="display">` or by adding `class="display"`
   to a custom heading element. Combine with size tokens — e.g.
   `class="display"` with `font-size: var(--font-size-4xl)`.
   ========================================== */

.display {
    font-family: var(--font-family-display);
    font-weight: var(--font-weight-display);
    letter-spacing: var(--font-display-tracking);
    line-height: var(--font-display-leading);
}

/* Larger sizes want tighter tracking — keeps the optical balance. */
.display.display--tightest,
.display[data-size="5xl"] {
    letter-spacing: var(--tracking-tightest);
    line-height: var(--leading-display);
}

/* ==========================================
   APP LAYOUT
   ========================================== */

.console-app {
    min-height: 100vh;
    width: 100%;
    background: var(--color-bg-primary);
}

/* Sync with sidebar width transition (sidebar/collapsed.css) for smooth collapse. */
.console-main {
    margin-left: var(--sidebar-width);
    padding-top: 72px;
    min-height: 100vh;
    background: var(--color-bg-primary);
    transition: margin-left var(--transition-base);
}

/* Low Credit Warning Banner */
.credit-warning-banner {
    margin-left: var(--sidebar-width);
    padding: var(--space-2) var(--space-4);
    background: var(--brand-blue-600);
    border-bottom: 1px solid var(--gold-500);
    border-left: 3px solid var(--gold-500);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
    transition: margin-left var(--transition-base);
}

/* Critical state */
.credit-warning-banner--critical {
    border-bottom-color: var(--red-400);
    border-left-color: var(--red-400);
}

.credit-warning-banner__content {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-sm);
    color: var(--gold-500);
    font-variant-numeric: tabular-nums;
}

.credit-warning-banner--critical .credit-warning-banner__content {
    color: var(--accent-text-red);
}

.credit-warning-banner__content > i {
    font-size: var(--text-base);
    flex-shrink: 0;
}

/* Mini progress bar inline */
.credit-warning-banner__mini-bar {
    width: 48px;
    height: 4px;
    background: var(--brand-blue-500);
    border-radius: 2px;
    overflow: hidden;
    flex-shrink: 0;
}

.credit-warning-banner__mini-fill {
    height: 100%;
    background: var(--gold-500);
    border-radius: 2px;
    transition: width 0.3s ease;
}

.credit-warning-banner--critical .credit-warning-banner__mini-fill {
    background: var(--red-400);
}

.credit-warning-banner__cta {
    padding: var(--space-1) var(--space-3);
    background: var(--emerald-500);
    color: var(--brand-blue-700);
    border-radius: var(--radius-sm);
    font-size: var(--text-xs);
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    transition: background 0.15s ease;
}

.credit-warning-banner__cta:hover {
    background: var(--emerald-600);
}

.credit-warning-banner__close {
    background: none;
    border: none;
    color: var(--text-tertiary);
    cursor: pointer;
    padding: var(--space-1);
    font-size: var(--text-sm);
}

.credit-warning-banner__close:hover {
    color: var(--text-secondary);
}

/* Consultant context banner — see components/consultant-context-banner.css */

/* Sidebar collapsed state (desktop only) */
@media (min-width: 1025px) {
    html.sidebar-collapsed .console-main {
        margin-left: var(--sidebar-width-collapsed);
    }
}

/* Page content max-width when sidebar visible (desktop only) */
@media (min-width: 1025px) {
    html:not(.new-layout):not(.sidebar-collapsed) .now-page,
    html:not(.new-layout):not(.sidebar-collapsed) .me-page,
    html:not(.new-layout):not(.sidebar-collapsed) .okrs-page,
    html:not(.new-layout):not(.sidebar-collapsed) .kpis-page,
    html:not(.new-layout):not(.sidebar-collapsed) .projects-page,
    html:not(.new-layout):not(.sidebar-collapsed) .team-page,
    html:not(.new-layout):not(.sidebar-collapsed) .settings-page,
    html:not(.new-layout):not(.sidebar-collapsed) .sources-page,
    html:not(.new-layout):not(.sidebar-collapsed) .strategy-page,
    html:not(.new-layout):not(.sidebar-collapsed) .tasks-page {
        max-width: 880px;
    }
}

/* ==========================================
   TYPOGRAPHY
   ========================================== */

h1, h2, h3, h4, h5, h6 {
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-primary);
    line-height: var(--line-height-tight);
}

h1 {
    font-size: var(--font-size-2xl);
    letter-spacing: var(--letter-spacing-tight);
}

h2 {
    font-size: var(--font-size-xl);
    letter-spacing: var(--letter-spacing-tight);
}

h3 {
    font-size: var(--font-size-lg);
}

h4 {
    font-size: var(--font-size-base);
}

p {
    color: var(--color-text-secondary);
    line-height: var(--line-height-relaxed);
}

a {
    color: var(--color-accent);
    text-decoration: none;
    transition: color 0.2s ease;
}

a:hover:not(.btn-primary):not(.btn-secondary):not(.document-card-cta):not([class*="btn"]):not(.admin-nav-link):not(.admin-row-action):not(.admin-sidebar-link):not(.admin-back-link):not(.sidebar-nav-item):not(.page-tab):not(.page-tab-action):not(.sub-tab-rail__tab):not(.icon-rail__item):not(.sr-ai-card__ask-more):not(.me-now-link):not(.exec-early-banner__cta):not([class*="toteutus__empty"]):not([class*="toteutus__partial"]):not([class*="toteutus__kr-title"]):not([class*="toteutus__obj-name"]):not([class*="toteutus__initiative-name"]):not([class*="toteutus__scope-cta"]):not([class*="toteutus__create-opt"]):not(.qc-wizard-link):not(.deepen-tile):not(.module-card):not(.phase-hero__cta):not(.phase-hero__step):not(.now-setup__cta-primary):not(.nv-btn-p):not(.nv-btn-s):not([class*="nv-pc"]):not([class*="nv-chain"]):not([class*="nv-card"]):not([class*="nv-chat"]):not([class*="nv-team"]):not([class*="nv-ai-leader"]):not([class*="console-hero__stat"]):not([class*="now-foot__link"]):not([class*="s3-"]) {
    color: var(--color-accent-hover);
}

strong {
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-primary);
}

/* ==========================================
   LISTS
   ========================================== */

ul, ol {
    list-style: none;
}

/* ==========================================
   IMAGES
   ========================================== */

img {
    max-width: 100%;
    height: auto;
    display: block;
}

/* ==========================================
   UTILITIES
   ========================================== */

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

.text-secondary {
    color: var(--color-text-secondary);
}

.text-primary {
    color: var(--color-text-primary);
}

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

.text-success {
    color: var(--color-success);
}

.text-warning {
    color: var(--color-warning);
}

.text-error {
    color: var(--color-error);
}

.text-sm {
    font-size: var(--font-size-sm);
}

.text-xs {
    font-size: var(--font-size-xs);
}

.font-medium {
    font-weight: var(--font-weight-medium);
}

.font-semibold {
    font-weight: var(--font-weight-semibold);
}

.font-bold {
    font-weight: var(--font-weight-bold);
}

/* ==========================================
   SPACING UTILITIES
   ========================================== */

.mt-1 { margin-top: var(--space-1); }
.mt-2 { margin-top: var(--space-2); }
.mt-3 { margin-top: var(--space-3); }
.mt-4 { margin-top: var(--space-4); }
.mt-5 { margin-top: var(--space-5); }
.mt-6 { margin-top: var(--space-6); }

/* ==========================================
   EMPTY STATES
   ========================================== */

.empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-3);
    padding: var(--space-8) var(--space-6);
    background: var(--glass-bg);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius-lg);
    text-align: center;
    color: var(--color-text-secondary);
}

.empty-state-icon {
    width: 48px;
    height: 48px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--radius-lg);
    background: var(--overlay-white-4);
    font-size: 1.25rem;
    color: var(--color-text-muted);
    margin-bottom: var(--space-1);
}

/* Accent variants for more inviting empty states */
.empty-state-icon--emerald {
    background: var(--emerald-alpha-10);
    color: var(--emerald-500);
}

.empty-state-icon--indigo {
    background: rgba(99, 102, 241, 0.1);
    color: var(--accent-text-indigo);
}

.empty-state-icon--blue {
    background: var(--blue-600-transparent);
    color: var(--accent-text-blue);
}

.empty-state-title {
    font-size: var(--font-size-base);
    font-weight: var(--font-weight-semibold);
    color: var(--color-text-primary);
}

.empty-state-text {
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
    max-width: 360px;
    line-height: 1.5;
}

.empty-state-actions {
    display: flex;
    gap: var(--space-3);
    justify-content: center;
    margin-top: var(--space-2);
    flex-wrap: wrap;
}

.mb-1 { margin-bottom: var(--space-1); }
.mb-2 { margin-bottom: var(--space-2); }
.mb-3 { margin-bottom: var(--space-3); }
.mb-4 { margin-bottom: var(--space-4); }
.mb-5 { margin-bottom: var(--space-5); }
.mb-6 { margin-bottom: var(--space-6); }

.gap-1 { gap: var(--space-1); }
.gap-2 { gap: var(--space-2); }
.gap-3 { gap: var(--space-3); }
.gap-4 { gap: var(--space-4); }

/* ==========================================
   FLEX UTILITIES
   ========================================== */

.flex {
    display: flex;
}

.flex-col {
    flex-direction: column;
}

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

.items-start {
    align-items: flex-start;
}

.justify-center {
    justify-content: center;
}

.justify-between {
    justify-content: space-between;
}

.flex-1 {
    flex: 1;
}

.flex-shrink-0 {
    flex-shrink: 0;
}

/* ==========================================
   GRID UTILITIES
   ========================================== */

.grid {
    display: grid;
}

.grid-cols-2 {
    grid-template-columns: repeat(2, 1fr);
}

.grid-cols-3 {
    grid-template-columns: repeat(3, 1fr);
}

.grid-cols-4 {
    grid-template-columns: repeat(4, 1fr);
}

/* ==========================================
   ANIMATIONS
   ========================================== */

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(4px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes slideIn {
    from {
        opacity: 0;
        transform: translateX(-8px);
    }
    to {
        opacity: 1;
        transform: translateX(0);
    }
}

@keyframes scaleIn {
    from {
        opacity: 0;
        transform: scale(0.95);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}

.animate-fade-in {
    animation: fadeIn 0.2s ease-out;
}

.animate-slide-in {
    animation: slideIn 0.2s ease-out;
}

.animate-scale-in {
    animation: scaleIn 0.2s ease-out;
}

/* ==========================================
   SCROLLBAR
   ========================================== */

::-webkit-scrollbar {
    width: 8px;
    height: 8px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    /* Changed: rgba(255,255,255,0.1) -> var(--overlay-white-10) for light theme support */
    background: var(--overlay-white-10);
    border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
    /* Changed: rgba(255,255,255,0.2) -> var(--overlay-white-20) for light theme support */
    background: var(--overlay-white-20);
}

/* ==========================================
   SELECTION
   ========================================== */

::selection {
    /* Changed: rgba(50,213,131,0.3) -> var(--emerald-alpha-30) for consistent theming */
    background: var(--emerald-alpha-30);
    color: var(--color-text-primary);
}

/* ==========================================
   RESPONSIVE - MOBILE
   ========================================== */

@media (max-width: 1024px) {
    .hide-mobile {
        display: none !important;
    }
}

@media (min-width: 1025px) {
    .hide-desktop {
        display: none !important;
    }
}

/* ==========================================
   VISUALLY HIDDEN (a11y)
   Element stays in DOM and focusable, hidden from view
   ========================================== */

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

/* ==========================================
   REDUCED MOTION (a11y, WCAG 2.3.3)
   Globaali katkaisija: kun käyttäjä on pyytänyt vähennettyä liikettä,
   kaikki animaatiot ja siirtymät kutistuvat käytännössä hetkellisiksi.
   0.01ms (ei 0) jättää animationend/transitionend-eventit ehjiksi,
   joten JS-logiikka joka odottaa niitä ei jää jumiin. Sivukohtaisia
   @media-blokkeja ei tämän jälkeen tarvita erikseen.
   ========================================== */

@media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
}
