/*
 * Aplikasi Andalan brand theme for BeerCSS (Material 3 Expressive).
 * Shared by the storefront AND the admin panel. Load it AFTER beer.min.css.
 *
 * Brand color: Strong Blue #0078D4.
 *
 * The palette below was generated from #0078D4 with Material's dynamic color
 * algorithm (material-dynamic-colors), with ONE deliberate deviation: the
 * algorithm darkens the light-mode primary to #0060AB, but the brand color
 * must be THE button color — so `--primary` is pinned to the exact #0078D4.
 * White text on #0078D4 has a 4.53:1 contrast ratio (passes WCAG AA).
 *
 * Dark mode follows the Material 3 rule of using a light tone of the brand
 * color (#A3C9FF), because #0078D4 text on a dark surface would fail AA.
 *
 * The theme is static CSS on purpose: no runtime theme generation, no flash of
 * wrong colors, and no inline styles (keeps the strict CSP intact).
 * To rebrand: generate a palette from your color at https://www.beercss.com
 * (or with material-dynamic-colors) and replace the two blocks below.
 */

:root,
body.light {
  --primary: #0078d4;
  --on-primary: #ffffff;
  --primary-container: #d3e3ff;
  --on-primary-container: #001c39;
  --secondary: #545f71;
  --on-secondary: #ffffff;
  --secondary-container: #d8e3f8;
  --on-secondary-container: #111c2b;
  --tertiary: #6d5677;
  --on-tertiary: #ffffff;
  --tertiary-container: #f5d9ff;
  --on-tertiary-container: #261430;
  --error: #ba1a1a;
  --on-error: #ffffff;
  --error-container: #ffdad6;
  --on-error-container: #410002;
  --background: #fdfcff;
  --on-background: #1a1c1e;
  --surface: #faf9fd;
  --on-surface: #1a1c1e;
  --surface-variant: #dfe2eb;
  --on-surface-variant: #43474e;
  --outline: #73777f;
  --outline-variant: #c3c6cf;
  --shadow: #000000;
  --scrim: #000000;
  --inverse-surface: #2f3033;
  --inverse-on-surface: #f1f0f4;
  --inverse-primary: #a3c9ff;
  --surface-dim: #dad9dd;
  --surface-bright: #faf9fd;
  --surface-container-lowest: #ffffff;
  --surface-container-low: #f4f3f7;
  --surface-container: #eeedf1;
  --surface-container-high: #e8e8eb;
  --surface-container-highest: #e3e2e6;
}

body.dark {
  --primary: #a3c9ff;
  --on-primary: #00315c;
  --primary-container: #004883;
  --on-primary-container: #d3e3ff;
  --secondary: #bcc7db;
  --on-secondary: #263141;
  --secondary-container: #3c4758;
  --on-secondary-container: #d8e3f8;
  --tertiary: #d9bde3;
  --on-tertiary: #3c2946;
  --tertiary-container: #543f5e;
  --on-tertiary-container: #f5d9ff;
  --error: #ffb4ab;
  --on-error: #690005;
  --error-container: #93000a;
  --on-error-container: #ffb4ab;
  --background: #1a1c1e;
  --on-background: #e3e2e6;
  --surface: #121316;
  --on-surface: #e3e2e6;
  --surface-variant: #43474e;
  --on-surface-variant: #c3c6cf;
  --outline: #8d9199;
  --outline-variant: #43474e;
  --shadow: #000000;
  --scrim: #000000;
  --inverse-surface: #e3e2e6;
  --inverse-on-surface: #2f3033;
  --inverse-primary: #0060ab;
  --surface-dim: #121316;
  --surface-bright: #38393c;
  --surface-container-lowest: #0d0e11;
  --surface-container-low: #1a1c1e;
  --surface-container: #1e2022;
  --surface-container-high: #292a2d;
  --surface-container-highest: #333538;
}

/* ---------------------------------------------------------------------------
 * The app's own roles that both areas use (the storefront's others are in
 * storefront.css). Kept apart from the generated palette above, so a rebrand
 * that replaces those two blocks keeps them.
 * ------------------------------------------------------------------------- */

/* Sunken surfaces: the language toggle's track (components.css — the
   storefront's header and the admin panel's top bar), the storefront's
   insets (search, quantity steppers, code boxes …). */
:root,
body.light {
  --aa-inset: #f4f3f7;
}

body.dark {
  --aa-inset: #26282c;
}

/* ---------------------------------------------------------------------------
 * Typography — standard, readable sizes
 * ------------------------------------------------------------------------- */

:root {
  /* The exact brand color, for the rare spot that must not follow the mode. */
  --brand: #0078d4;

  /* The shop's typeface (decision 134; self-hosted, css/fonts.css). */
  --font:
    "Google Sans Flex", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;

  /* 1rem = the visitor's browser default (16px unless they changed it) —
     never set a px size here, it would override their accessibility setting. */
  --size: 1rem;
}

/* The browser's own parts (scrollbars, form controls, the canvas behind the
   page) follow the visitor's choice: light by default — the page's
   <meta name="color-scheme" content="light">, even when the OS is in dark
   mode — and dark only when they chose dark (theme-init.js / app.js set
   <html data-theme>). */
:root[data-theme="dark"] {
  color-scheme: dark;
}

/* BeerCSS defaults body text to 14px; 16px / 1.5 is the readable web standard
   (Material "body large"). Decision 134, for Google Sans Flex:
   - tabular figures everywhere: the admin's grids, totals and counts line
     up in columns, as they did with Roboto Flex, whose digits were all one
     width — Google Sans Flex's are proportional unless asked;
   - no extra tracking: BeerCSS spaces body text 0.5 px a letter, Material's
     value for Roboto; Google's own Material sets Google Sans at 0. With it
     the admin's grids outgrew their cards at 1440 px (the products' row
     actions went off the edge). The storefront keeps its own 0.1 px (.aa). */
body {
  font-size: 1rem;
  line-height: 1.5rem;
  letter-spacing: 0;
  font-optical-sizing: auto;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

/* BeerCSS maps h1–h6 to Material's *display* scale (57px → 24px), which is
   oversized for regular page content. Headings use a conventional web scale
   instead; the big display sizes stay available through `.large` or the
   `.display-title` helper below. */
h1,
.h1 {
  font-size: 2.25rem;
  line-height: 2.75rem;
  font-weight: 500;
  letter-spacing: -0.01em;
}
h2,
.h2 {
  font-size: 1.75rem;
  line-height: 2.25rem;
  font-weight: 500;
  letter-spacing: -0.005em;
}
h3,
.h3 {
  font-size: 1.5rem;
  line-height: 2rem;
  font-weight: 500;
}
h4,
.h4 {
  font-size: 1.375rem;
  line-height: 1.75rem;
  font-weight: 500;
}
h5,
.h5 {
  font-size: 1.25rem;
  line-height: 1.75rem;
  font-weight: 500;
}
h6,
.h6 {
  font-size: 1.125rem;
  line-height: 1.5rem;
  font-weight: 500;
}

/* Material 3 Expressive "emphasized display": fluid between phone and desktop. */
.display-title {
  font-size: clamp(2.25rem, 1.4rem + 3.6vw, 3.5625rem);
  line-height: 1.12;
  font-weight: 600;
  letter-spacing: -0.02em;
}

.lead-text {
  font-size: 1.125rem;
  line-height: 1.75rem;
  color: var(--on-surface-variant);
}

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

/* No face for code here: each area sets its own (decision 137) — the
   admin's in Roboto Mono (admin.css, `.mono` and code), the storefront's in
   Roboto (storefront.css `.code-text`, `--font-code`; its two <code>s, the
   home hero's formula bar and an article's formula, name their face in
   their pages' rules). */

/* Long hashes / ids must wrap instead of stretching their card. */
.break-anywhere {
  overflow-wrap: anywhere;
}

/* ---------------------------------------------------------------------------
 * Light / dark variants (the toggle's icons, the storefront logo): both are in
 * the markup, CSS shows the right one (so nothing flickers while scripts load).
 * ------------------------------------------------------------------------- */

body:not(.dark) .when-dark,
body.dark .when-light {
  display: none;
}

/* ---------------------------------------------------------------------------
 * htmx request indicator. htmx normally injects these rules as an inline
 * <style>, which the CSP forbids (`includeIndicatorStyles: false` in the
 * layouts) — so they live here.
 * ------------------------------------------------------------------------- */

.htmx-indicator {
  opacity: 0;
  visibility: hidden;
  transition: opacity 200ms ease-in;
}

.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  opacity: 1;
  visibility: visible;
}

/* Keyboard users must always see where they are. */
:focus-visible {
  outline: 0.125rem solid var(--primary);
  outline-offset: 0.125rem;
}

/*
 * Accessibility: visitors who ask their OS for reduced motion get (almost) no
 * animation. `!important` is the point here — this must beat every component
 * rule regardless of specificity — so the linter rule is switched off for
 * exactly this block.
 */
/* biome-ignore-start lint/complexity/noImportantStyles: reduced-motion override must win over all component styles */
@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;
  }
}
/* biome-ignore-end lint/complexity/noImportantStyles: see above */
