/*
 * The brand palette as plain `:root` custom properties — for consumers WITHOUT Tailwind 4
 * (issue #29). Tailwind apps get these same `--color-*` vars from `theme.css`'s `@theme` block
 * (and the matching utilities); a non-Tailwind app (walkup, whose styling is hand-rolled CSS)
 * can't, so it imports this file to resolve the `var(--color-*)` references in `@lazar/ui/brut.css`.
 *
 * Values are mirrored from `theme.css` — keep the two in sync (there is no build step). These are
 * the STATIC palette; the runtime brutalist line/shadow that flip in dark mode live in tokens.css.
 */

:root {
  --color-lemon-50: #fffbeb;
  --color-lemon-100: #fef3c7;
  --color-lemon-200: #fde68a;
  --color-lemon-300: #fcd34d;
  --color-lemon-400: #fbbf24;
  --color-lemon-500: #ffe94a;
  --color-lemon-600: #f59e0b;
  --color-lemon-700: #d97706;

  --color-crust-500: #92400e;
  --color-zest-500: #84cc16;
  --color-zest-600: #65a30d;
  --color-coral-500: #fb7185;
  --color-coral-600: #e11d48;
  --color-sky-brut: #38bdf8;
  --color-grape-500: #c084fc;

  --color-ink: #0a0a0a;
  --color-ink-soft: #2a2a2a;
  --color-cream: #fffbeb;
  --color-paper: #ffffff;
  --color-charcoal: #171717;

  /* Static placeholder/hint grey for empty inputs (issue #136). Mirrored from theme.css —
     keep in sync. Does NOT flip with dark mode; use the dark-flipping `--brut-ink-soft`
     (tokens.css) for secondary text instead. */
  --color-muted: #9ca3af;
}

/*
 * Lazar ecosystem design tokens — runtime CSS custom properties (issue #29).
 *
 * These are plain CSS variables (not Tailwind `@theme` entries) because they flip with dark
 * mode at runtime: the brutalist line + hard-offset shadow are darker on light backgrounds and
 * a warm grey in dark mode. Tailwind `@theme` values are static, so the line/shadow live here.
 *
 * Dark mode rides `prefers-color-scheme` — there is intentionally no `.dark` class or
 * `@custom-variant dark` anywhere in the system. The consuming apps' `dark:` utilities resolve
 * to the system-preference default; introducing a class toggle would silently break all of them.
 *
 * Radius and duration tokens are added here so components stop hard-coding 3px/4px/6px and
 * 80ms/120ms — the values are unchanged, only named.
 */

:root {
  color-scheme: light dark;

  --brut-line: #0a0a0a;
  --brut-line-soft: #2a2a2a;
  --brut-shadow-sm: 2px 2px 0 0 #0a0a0a;
  --brut-shadow: 4px 4px 0 0 #0a0a0a;
  --brut-shadow-lg: 6px 6px 0 0 #0a0a0a;

  /* Muted/secondary text. Flips so it stays readable on a dark surface (near-black on light,
     a warm light grey on dark) — the static `--color-ink-soft` can't, which is why this lives
     here with the other dark-flipping runtime tokens rather than in the `@theme` palette. */
  --brut-ink-soft: #2a2a2a;

  --radius-sm: 3px;
  --radius-md: 4px;
  --radius-lg: 6px;

  --duration-fast: 80ms;
  --duration-normal: 120ms;
  --duration-slow: 200ms;
}

@media (prefers-color-scheme: dark) {
  :root {
    --brut-line: #a89f82;
    --brut-line-soft: #6b624f;
    --brut-shadow-sm: 2px 2px 0 0 #7d735a;
    --brut-shadow: 4px 4px 0 0 #7d735a;
    --brut-shadow-lg: 6px 6px 0 0 #7d735a;
    --brut-ink-soft: #d6ccae;
  }
}

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

.animate-entry-in {
  animation: fadeIn var(--duration-slow) ease-out;
}

/* The live/busy pulse used by the Ping component (issue #29). Moved here from walkup's
   brutpop.css so both apps share one definition. Pure opacity/scale — no color, no inline
   style, so it's safe under a strict `style-src 'self'` CSP. */
@keyframes brutPing {
  0% {
    transform: scale(0.8);
    opacity: 1;
  }
  75%,
  100% {
    transform: scale(2);
    opacity: 0;
  }
}

/*
 * @lazar/ui — brutalist component styles (issue #29).
 *
 * The `.brut-*` primitive layer, extracted verbatim from time-tracker's index.css. The typed
 * React components in this package emit these class names; this file is the CSS contract behind
 * them. Consumers import it once:
 *
 *   @import "@lazar/ui/brut.css";
 *
 * It depends on the tokens in `@lazar/design-tokens` (the `--brut-*`, `--radius-*`, `--color-*`
 * custom properties), so import the design-tokens CSS first. Literal 3/4/6px radii and 80/120ms
 * durations from the original were replaced with the radius/duration tokens; computed output is
 * unchanged. Dark-mode rules ride `prefers-color-scheme` (no `.dark` class).
 *
 * Known gap: a few incidental values are still raw hex here (the secondary placeholder grey
 * `#6b7280`, danger-hover tints `#fee2e2`/`#450a0a`, dark neutral surfaces `#1f1f1f`/`#2a2a2a`).
 * They're a faithful verbatim port — promoting them to named tokens (a danger-tint, dark surfaces)
 * is part of the deliberate token-normalization pass the research doc defers. The primary input
 * placeholder grey was promoted to `--color-muted` in @lazar/design-tokens (issue #136). As the
 * source of truth, the package is allowed to hold raw values; apps are not.
 */

@layer components {
  .brut-card {
    background: var(--color-paper);
    border: 3px solid var(--brut-line);
    border-radius: var(--radius-lg);
    box-shadow: var(--brut-shadow-lg);
  }

  .brut-card-sub {
    background: var(--color-lemon-50);
    border: 2px solid var(--brut-line);
    border-radius: var(--radius-md);
  }

  .brut-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.875rem;
    border: 2px solid var(--brut-line);
    border-radius: var(--radius-md);
    background: var(--color-paper);
    color: var(--brut-line);
    font-weight: 600;
    box-shadow: var(--brut-shadow-sm);
    cursor: pointer;
    transition: transform var(--duration-fast) ease, box-shadow var(--duration-fast) ease,
      background var(--duration-normal) ease;
    white-space: nowrap;
  }
  .brut-btn:hover {
    background: var(--color-lemon-100);
  }
  .brut-btn:active {
    transform: translate(2px, 2px);
    box-shadow: 0 0 0 0 var(--brut-line);
  }
  .brut-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    box-shadow: var(--brut-shadow-sm);
    transform: none;
    background: var(--color-paper);
  }

  .brut-btn-primary {
    background: var(--color-lemon-500);
    color: var(--color-ink);
  }
  .brut-btn-primary:hover {
    background: var(--color-lemon-400);
  }

  .brut-btn-danger {
    background: var(--color-coral-500);
    color: var(--color-ink);
  }
  .brut-btn-danger:hover {
    background: var(--color-coral-600);
    color: var(--color-cream);
  }

  .brut-btn-success {
    background: var(--color-zest-500);
    color: var(--color-ink);
  }
  .brut-btn-success:hover {
    background: var(--color-zest-600);
    color: var(--color-cream);
  }

  .brut-btn-icon {
    padding: 0.375rem;
    min-width: auto;
  }

  .brut-input,
  .brut-select {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 2px solid var(--brut-line);
    border-radius: var(--radius-md);
    background: var(--color-paper);
    color: var(--color-ink);
    font-weight: 500;
    transition: box-shadow var(--duration-fast) ease;
  }
  .brut-input:focus,
  .brut-select:focus {
    outline: none;
    box-shadow: var(--brut-shadow-sm);
  }
  .brut-input::placeholder {
    color: var(--color-muted);
  }

  .brut-kbd {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.25rem;
    padding: 0.0625rem 0.375rem;
    border: 2px solid var(--brut-line);
    border-radius: var(--radius-sm);
    background: var(--color-lemon-100);
    color: var(--color-ink);
    font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
    font-size: 0.6875rem;
    font-weight: 700;
    line-height: 1.4;
    box-shadow: 1.5px 1.5px 0 0 var(--brut-line);
  }

  .brut-badge {
    display: inline-flex;
    align-items: center;
    /* Space a leading element (e.g. a Ping dot) from the label text. Inert for a single-child
       text badge — there's nothing for the gap to sit between (issue #68). */
    gap: 0.375rem;
    padding: 0.125rem 0.5rem;
    border: 2px solid var(--brut-line);
    border-radius: var(--radius-sm);
    font-size: 0.75rem;
    font-weight: 700;
    line-height: 1.4;
    box-shadow: 1.5px 1.5px 0 0 var(--brut-line);
  }

  .brut-divider {
    border-color: var(--brut-line);
    border-style: solid;
    border-width: 0 0 2px 0;
  }

  .brut-divider-thin {
    border-color: var(--brut-line-soft);
    border-style: solid;
    border-width: 0 0 1px 0;
  }

  /* Hard-offset dropdown menu */
  .brut-menu {
    background: var(--color-paper);
    border: 2px solid var(--brut-line);
    border-radius: var(--radius-md);
    box-shadow: var(--brut-shadow);
    overflow: hidden;
  }
  .brut-menu-item {
    display: block;
    width: 100%;
    text-align: left;
    padding: 0.5rem 0.875rem;
    font-size: 0.875rem;
    font-weight: 500;
    cursor: pointer;
  }
  .brut-menu-item:hover {
    background: var(--color-lemon-100);
  }
  .brut-menu-item-danger {
    color: var(--color-coral-600);
  }
  .brut-menu-item-danger:hover {
    background: #fee2e2;
  }
}

@media (prefers-color-scheme: dark) {
  .brut-card {
    background: var(--color-charcoal);
  }
  .brut-card-sub {
    background: #1f1f1f;
  }
  .brut-btn {
    background: var(--color-charcoal);
  }
  .brut-btn:hover {
    background: #2a2a2a;
  }
  /* Re-state modifier backgrounds so the dark .brut-btn rule above doesn't win on source order. */
  .brut-btn-primary {
    background: var(--color-lemon-500);
    color: var(--color-ink);
  }
  .brut-btn-primary:hover {
    background: var(--color-lemon-400);
  }
  .brut-btn-danger {
    background: var(--color-coral-500);
    color: var(--color-ink);
  }
  .brut-btn-danger:hover {
    background: var(--color-coral-600);
    color: var(--color-cream);
  }
  .brut-input,
  .brut-select {
    background: var(--color-charcoal);
    color: var(--color-cream);
  }
  .brut-input::placeholder {
    color: #6b7280;
  }
  .brut-kbd {
    background: var(--color-lemon-200);
  }
  .brut-menu {
    background: var(--color-charcoal);
  }
  .brut-menu-item:hover {
    background: #2a2a2a;
  }
  .brut-menu-item-danger {
    color: var(--color-coral-500);
  }
  .brut-menu-item-danger:hover {
    background: #450a0a;
  }
}

/* ============================================================================
   Issue #29, second wave: Dialog, ConfirmDialog, Toast, Alert, FormField,
   SegmentedControl, Panel, EmptyState, Ping.

   These are authored as plain CSS `.brut-*` classes (NOT Tailwind utilities) so
   they render identically in time-tracker (Tailwind 4) AND walkup (no Tailwind,
   links this sheet directly). No inline `style` is used for anything visual, so
   they're safe under walkup's strict `style-src 'self'` CSP.
   ========================================================================== */

@layer components {
  /* ----- Dialog / ConfirmDialog ----- */
  .brut-dialog-backdrop {
    position: fixed;
    inset: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: color-mix(in srgb, var(--color-ink) 40%, transparent);
  }
  .brut-dialog {
    width: 100%;
    max-width: 24rem;
    padding: 1.5rem;
  }
  .brut-dialog-md {
    max-width: 32rem;
  }
  .brut-dialog-lg {
    max-width: 42rem;
  }
  .brut-dialog-title {
    margin: 0 0 0.5rem;
    font-size: 1.125rem;
    font-weight: 900;
    color: var(--color-ink);
  }
  .brut-dialog-message {
    margin: 0 0 1.5rem;
    font-size: 0.875rem;
    color: var(--color-ink-soft);
  }
  /* Content region for a free-form dialog body (issue #67): stacks arbitrary fields with a
     consistent vertical rhythm so adjacent inputs don't sit flush. Layout-only (flex + gap), no
     variant or visual state — so it's deliberately not in the story-per-variant gate (#64). */
  .brut-dialog-body {
    display: flex;
    flex-direction: column;
    gap: 1rem;
  }
  .brut-dialog-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.75rem;
  }
  /* Separate the action row from the body above it. Scoped to the adjacent-sibling pair so it
     only fires for a free-form body dialog; ConfirmDialog (title + message + actions, no body)
     keeps its existing message margin-bottom rhythm untouched (issue #67). */
  .brut-dialog-body + .brut-dialog-actions {
    margin-top: 1.5rem;
  }
  /*
   * Body-scroll-lock while a Dialog is open (issue #50). Toggled on <body> by the Dialog component
   * — a class, not inline style, so walkup's `style-src 'self'` CSP is satisfied. `scrollbar-gutter:
   * stable` reserves the scrollbar's width while `overflow: hidden` removes it, so the page doesn't
   * shift sideways on open/close.
   */
  .brut-scroll-lock {
    overflow: hidden;
    scrollbar-gutter: stable;
  }

  /* ----- Toast ----- */
  .brut-toast-viewport {
    position: fixed;
    bottom: 1.5rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 100;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 18rem;
    max-width: 28rem;
  }
  .brut-toast {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.75rem 1rem;
    border: 3px solid var(--color-ink);
    border-radius: var(--radius-md);
    box-shadow: var(--brut-shadow);
    animation: fadeIn var(--duration-slow) ease-out;
  }
  .brut-toast-success {
    background: var(--color-zest-500);
    color: var(--color-ink);
  }
  .brut-toast-error {
    background: var(--color-coral-500);
    color: var(--color-ink);
  }
  .brut-toast-warning {
    background: var(--color-lemon-500);
    color: var(--color-ink);
  }
  .brut-toast-info {
    background: var(--color-sky-brut);
    color: var(--color-ink);
  }
  .brut-toast-message {
    flex: 1;
    font-size: 0.875rem;
    font-weight: 700;
  }
  .brut-toast-action {
    cursor: pointer;
    font-size: 0.875rem;
    font-weight: 900;
    white-space: nowrap;
    text-decoration: underline;
    text-underline-offset: 2px;
  }
  .brut-toast-action:hover {
    text-decoration: none;
  }
  .brut-toast-dismiss {
    cursor: pointer;
    margin-left: 0.25rem;
    display: inline-flex;
    opacity: 0.7;
  }
  .brut-toast-dismiss:hover {
    opacity: 1;
  }

  /* ----- Alert (static tonal notice) ----- */
  .brut-alert {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    padding: 0.75rem 1rem;
    border: 2px solid var(--color-ink);
    border-radius: var(--radius-md);
    box-shadow: var(--brut-shadow-sm);
    color: var(--color-ink);
  }
  .brut-alert-info {
    background: var(--color-sky-brut);
  }
  .brut-alert-warning {
    background: var(--color-lemon-500);
  }
  .brut-alert-danger {
    background: var(--color-coral-500);
  }
  .brut-alert-success {
    background: var(--color-zest-500);
  }
  /*
   * walkup domain tones (issue #54) — the "two zeros" distinction absorbed from walkup's retired
   * NoticeCard. These pin the old `.evaluate-notice` look exactly in light mode: tighter padding,
   * heavier body weight, and the flipping `--brut-line` border (the brut.css house border, which
   * the brand-tone alerts above happen to render with the static `--color-ink` instead).
   *   - throttle: lemon — a 429 "slow down", not an error (polite).
   *   - failure: coral — a pipeline/contract failure broke something (assertive).
   *   - down: paper — an unreachable/unavailable surface; "we just don't know".
   * `down` uses the static `--color-paper`/`--color-ink` like every other Alert tone, so it does
   * not adapt to dark mode the way walkup's bespoke notice did — a deliberate, scoped trade for a
   * single shared primitive (the package owns no flipping surface token, and aliasing walkup's
   * flip tokens into the package is forbidden). Light mode is byte-identical.
   */
  .brut-alert-throttle,
  .brut-alert-failure,
  .brut-alert-down {
    padding: 0.5rem 0.75rem;
    border-color: var(--brut-line);
  }
  .brut-alert-throttle .brut-alert-body,
  .brut-alert-failure .brut-alert-body,
  .brut-alert-down .brut-alert-body {
    font-weight: 700;
  }
  .brut-alert-throttle {
    background: var(--color-lemon-100);
    color: var(--color-ink);
  }
  .brut-alert-failure {
    background: var(--color-coral-500);
    color: var(--color-ink);
  }
  .brut-alert-down {
    background: var(--color-paper);
    color: var(--color-ink);
  }
  .brut-alert-title {
    margin: 0;
    font-size: 0.875rem;
    font-weight: 900;
  }
  .brut-alert-body {
    font-size: 0.875rem;
    font-weight: 500;
  }

  /* ----- FormField ----- */
  .brut-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
  }
  .brut-field-label {
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--color-ink);
  }
  .brut-field-error {
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--color-coral-600);
  }
  .brut-field-success {
    font-size: 0.75rem;
    font-weight: 700;
    color: var(--color-zest-600);
  }
  .brut-field-hint {
    font-size: 0.75rem;
    color: var(--color-ink-soft);
  }

  /* ----- SegmentedControl (row of Buttons) ----- */
  .brut-segmented {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 0.5rem;
  }

  /* ----- Tabs (single-select tab strip) ----- */
  .brut-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
  }
  .brut-tab {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.5rem 0.875rem;
    border: 2px solid var(--brut-line);
    border-radius: var(--radius-md);
    background: var(--color-paper);
    color: var(--brut-line);
    font-weight: 600;
    box-shadow: var(--brut-shadow-sm);
    cursor: pointer;
    white-space: nowrap;
    transition: transform var(--duration-fast) ease, box-shadow var(--duration-fast) ease,
      background var(--duration-normal) ease;
  }
  .brut-tab:hover {
    background: var(--color-lemon-100);
  }
  .brut-tab:active {
    transform: translate(2px, 2px);
    box-shadow: 0 0 0 0 var(--brut-line);
  }
  .brut-tab-active {
    background: var(--color-lemon-500);
    color: var(--color-ink);
  }
  .brut-tab-active:hover {
    background: var(--color-lemon-400);
  }

  /* ----- MultiSelectChips (multi-select toggle filter) ----- */
  .brut-chip-group {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
  }
  .brut-chip {
    display: inline-flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.5rem 0.875rem;
    border: 2px solid var(--brut-line);
    border-radius: var(--radius-md);
    background: var(--color-paper);
    color: var(--brut-line);
    font-weight: 600;
    box-shadow: var(--brut-shadow-sm);
    cursor: pointer;
    white-space: nowrap;
    transition: transform var(--duration-fast) ease, box-shadow var(--duration-fast) ease,
      background var(--duration-normal) ease;
  }
  .brut-chip:hover {
    background: var(--color-lemon-100);
  }
  .brut-chip:active {
    transform: translate(2px, 2px);
    box-shadow: 0 0 0 0 var(--brut-line);
  }
  .brut-chip-active {
    background: var(--color-lemon-500);
    color: var(--color-ink);
  }
  .brut-chip-active:hover {
    background: var(--color-lemon-400);
  }
  /* The leading color dot the time-tracker client filter passes via `leading`. The dot's
     background is consumer data; this only owns the ring/sizing so the consumer never hand-rolls
     border/layout. */
  .brut-chip-dot {
    height: 0.75rem;
    width: 0.75rem;
    border-radius: 9999px;
    border: 2px solid var(--color-ink);
    flex-shrink: 0;
  }

  /* ----- Panel (titled section card) ----- */
  .brut-panel {
    padding: 1rem;
  }
  .brut-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    margin-bottom: 0.75rem;
  }
  .brut-panel-title {
    margin: 0;
    font-size: 0.875rem;
    font-weight: 800;
    color: var(--color-ink);
  }

  /* ----- EmptyState ----- */
  .brut-empty {
    padding: 2rem;
    text-align: center;
  }

  /* ----- Ping (live/busy pulse dot) ----- */
  .brut-ping {
    position: relative;
    display: inline-flex;
    height: 0.5rem;
    width: 0.5rem;
  }
  .brut-ping::before {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: 9999px;
    background: currentColor;
    opacity: 0.75;
    animation: brutPing 1s cubic-bezier(0, 0, 0.2, 1) infinite;
  }
  .brut-ping::after {
    content: "";
    position: relative;
    height: 0.5rem;
    width: 0.5rem;
    border-radius: 9999px;
    background: currentColor;
  }

  /* ----- StatRow (icon/dot + label + value + optional badge) ----- */
  /* Structural only by design (issue #53): flex layout, gap, alignment, and the label's
     `flex:1; min-width:0` truncation basis. No typography/color/padding — consumers layer those
     per slot via the `*ClassName` props so a migrated row renders exactly as it did before. */
  .brut-statrow {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
  }
  .brut-statrow-leading {
    flex: none;
    display: inline-flex;
    align-items: center;
  }
  .brut-statrow-label {
    flex: 1;
    min-width: 0;
  }
  .brut-statrow-value {
    flex: none;
  }
  .brut-statrow-trailing {
    flex: none;
  }
}

/* ----- MetricRow (leading item + right-aligned figure) ----- */
/* Issue #63. A fresh `@layer components` block (same-named layers merge, so this is inside the
   components layer) appended after StatRow and before the trailing dark-mode media query — kept as
   one append-only block so the brut.css union with concurrent waves stays mechanical.
   Structural only: flex layout, `center` cross-axis alignment (these rows align center, unlike
   StatRow's baseline — a checked invariant of the two call sites), gap, and the LEADING slot's
   `flex:1; min-width:0` truncation basis. No typography/color/padding — consumers layer those per
   slot via the `*ClassName` props and on their own surface wrapper, so a migrated row renders
   exactly as it did before. */
@layer components {
  .brut-metric-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
  }
  .brut-metric-row-leading {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
  }
  .brut-metric-row-value {
    flex: none;
  }
}

/* Dark mode: only the text-on-surface colors flip (the pop/tonal backgrounds stay candy-bright,
   like the rest of the system). Backdrops/borders/shadows already use flipping tokens. */
@media (prefers-color-scheme: dark) {
  .brut-dialog-title {
    color: var(--color-cream);
  }
  .brut-dialog-message {
    color: color-mix(in srgb, var(--color-cream) 80%, transparent);
  }
  .brut-field-label {
    color: var(--color-cream);
  }
  .brut-field-error {
    color: var(--color-coral-500);
  }
  .brut-field-success {
    color: var(--color-zest-500);
  }
  .brut-field-hint {
    color: color-mix(in srgb, var(--color-cream) 70%, transparent);
  }
  .brut-panel-title {
    color: var(--color-cream);
  }
}


*, *::before, *::after { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
body {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
  background: var(--color-cream);
  color: var(--color-ink);
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
.auth-shell { width: 100%; max-width: 26rem; }
.auth-card { padding: 1.75rem; }
.auth-title { margin: 0 0 0.25rem; font-size: 1.5rem; font-weight: 800; }
.auth-subtitle { margin: 0 0 1.25rem; color: var(--brut-ink-soft); font-size: 0.95rem; }
.auth-form { display: flex; flex-direction: column; gap: 0.9rem; }
.auth-actions { margin-top: 0.4rem; }
.auth-actions .brut-btn { width: 100%; justify-content: center; }
.auth-alt { margin-top: 1.1rem; font-size: 0.9rem; text-align: center; color: var(--brut-ink-soft); }
.auth-alt a { color: var(--color-ink); font-weight: 700; }
.auth-deferred { margin-top: 1rem; }
