/*
 * The design system: the colour tokens every surface shares, and the two
 * components every surface renders. The login page, the admin dashboard and the
 * client portal all read this file; style.css and portal.css are layout only.
 *
 * The Twig pages <link> it ahead of style.css, and portal.css imports it so Vite
 * inlines it into the bundle. One file either way, so the two cannot drift.
 *
 * Tokens are light/dark pairs via light-dark(), which resolves against the used
 * `color-scheme`. That is why the three theme states are expressed there and
 * nowhere else. Baseline since 2024 (Chrome 123, Firefox 120, Safari 17.5).
 * See Theming in CLAUDE.md.
 */

/* No attribute follows the OS; an explicit choice overrides it. */
:root {
    color-scheme: light;
}

@media (prefers-color-scheme: dark) {
    /* Same specificity as the attribute rules below, so those must follow. */
    :root:not([data-theme="light"]) {
        color-scheme: dark;
    }
}

:root[data-theme="light"] {
    color-scheme: light;
}

:root[data-theme="dark"] {
    color-scheme: dark;
}

:root {
    /* Surfaces */
    --bg:             light-dark(#f6f7f9, #0f1117);
    --surface:        light-dark(#ffffff, #161b22);
    --surface-sunken: light-dark(#eef0f3, #0d1117);

    /* Borders */
    --line: light-dark(#e3e6ea, #30363d);

    /* Text */
    --ink:        light-dark(#14181d, #e1e4e8);
    --ink-strong: light-dark(#0b0e12, #c9d1d9);
    --muted:      light-dark(#67707a, #8b949e);
    --subtle:     light-dark(#8a929b, #6e7681);

    /* UI accent. Deliberately not the brand blue: this one has to stay legible
       on both surfaces, and its light value is a validated palette.js slot. */
    --accent: light-dark(#2f6feb, #58a6ff);

    /* Text on a solid accent or status fill, where the fill sets the contrast. */
    --on-solid: #ffffff;

    /* Pilot'in brand blue, logo only. Fixed: a brand colour that changes with
       the theme is not a brand colour. */
    --brand-blue: oklch(52.94% 0.272 266.38);

    /* The mark needs a tile only where the surface would swallow the blue. */
    --brand-tile: light-dark(transparent, #ffffff);

    /* Status. `partial` is the warning tier: a run that finished with errors. */
    --success:    light-dark(#1a9c5b, #52c41a);
    --success-bg: light-dark(#dcf5e6, #1b4332);
    --partial:    light-dark(#d1893a, #d4800a);
    --partial-bg: light-dark(#fdeccc, #3d1f00);
    --error:      light-dark(#cf3b3b, #f85149);
    --error-bg:   light-dark(#fbe0e0, #4a1c1c);

    /* The error notice on the dashboard is a surface, not a badge fill. */
    --error-surface: light-dark(#fdf1f1, #2d1117);
    --error-border:  light-dark(#b0202033, #f8514933);

    /* Badge fills with no status meaning */
    --info-bg:    light-dark(#dce9fd, #0d2d4a);
    --neutral-bg: light-dark(#e6e9ed, #2d333b);

    /* Primary button */
    --btn-primary:       light-dark(#1a7f37, #238636);
    --btn-primary-hover: light-dark(#22883c, #2ea043);

    /* Chart tooltip. Canvas cannot read a custom property, so SyncChart resolves
       this one through getComputedStyle. */
    --tooltip-bg: light-dark(#14181d, #2d333b);
}

/* Size is the only thing a surface overrides. */
.brand {
    --brand-logo-size: 1.15rem;

    display: flex;
    align-items: center;
    gap: 0.4rem;
}

/*
 * The mark keeps Pilot'in blue in both themes; on dark it gets --brand-tile,
 * a white plate, because the blue alone is too dark to read there. Masked, not
 * an <img>, so tile and mark are two colours out of one file.
 */
.brand__logo {
    flex: none;
    display: grid;
    place-items: center;
    width: var(--brand-logo-size);
    height: var(--brand-logo-size);
    background: var(--brand-tile);
    border-radius: calc(var(--brand-logo-size) / 4.5);
}

.brand__logo::before {
    content: '';
    width: 74%;
    height: 74%;
    background: var(--brand-blue);
    mask: url('/assets/pilot-in-logo.svg') center / contain no-repeat;
}

/* Present to a screen reader, absent to everyone else. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

.theme-toggle {
    display: inline-grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--surface);
    color: var(--muted);
    cursor: pointer;
}

.theme-toggle:hover {
    color: var(--ink);
}

/*
 * Shows the theme it would switch *to*: a moon while light, a sun while dark.
 * light-dark() carries colours, not images, so the swap needs all three theme
 * selectors, and the explicit ones must follow the media query to win.
 */
.theme-toggle__icon {
    width: 1.05rem;
    height: 1.05rem;
    background: currentColor;
    mask: url('/assets/icon-moon.svg') center / contain no-repeat;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .theme-toggle__icon {
        mask-image: url('/assets/icon-sun.svg');
    }
}

:root[data-theme="dark"] .theme-toggle__icon {
    mask-image: url('/assets/icon-sun.svg');
}

:root[data-theme="light"] .theme-toggle__icon {
    mask-image: url('/assets/icon-moon.svg');
}
