/* ============================================================================
   AirSign Marketing CSS — Minimal v2 (2026-04-24, audited 2026-04-26 v2.9;
   dedupe pass 2026-04-30)
   ============================================================================
   Linear / Vercel-style: monochrome surfaces, hairline borders, single brand
   accent, sharp typography, generous whitespace. Class names preserved for
   backwards compatibility with existing HTML.

   Authoring rules:
   - Semantic tokens at :root; dark mode via [data-theme="airsign"]
   - No heavy shadows (hairline borders instead)
   - No large mesh gradients (subtle single-stop radial at most)
   - Tailwind / DaisyUI utility classes still allowed in markup

   !important policy (re-audited 2026-05-03 — 35 real declarations, all
   load-bearing; +1 vs 2026-04-26 audit, no new categories):
   - Button color overrides (`.as-btn-*` color: white/black; also
     `.as-cinema-calc__seg button`, `.as-cinema-cta .as-btn-primary`,
     `.as-pricing-tile .btn.btn-outline`, `.as-subnav__cta`) — beat
     DaisyUI's `.btn` and link color rules across state combinations [×7]
   - Navbar transparency (`.as-page > nav.navbar`, `.as-nav` background +
     box-shadow:none, dark-theme override) — beat DaisyUI's opaque bg [×3]
   - `[x-cloak]` display:none — Alpine.js canonical FOUC prevention [×1]
   - DaisyUI flatten rules (`.card.bg-gradient-to-br`, `.card.shadow-xl/2xl`,
     `.as-cinema table.shadow-*`, `tr.bg-base-200` band override) —
     neutralise pre-design-system markup [×10]
   - Prose typography overrides (`.prose h2/h3/ul.list-disc`) — reassert
     design tokens against authored Tailwind utilities inside blog
     articles [×11]
   - `prefers-reduced-motion` overrides — industry standard [×3]
   New `!important` should not be added without a comment justifying it
   AND, ideally, a category in this list. If a new category is needed,
   bump the audit date and document it here.
   ========================================================================== */

/* Inter + Space Grotesk load from `<link>` in `partials/head-assets-*.html` (preconnect + stylesheet) — not `@import` here (blocks first paint). */

/* Tell native form controls, scrollbars, and mobile browser chrome intent */
:root,
html[data-theme='airsign-light'] {
  color-scheme: light;
}
html[data-theme='airsign'] {
  color-scheme: dark;
}

/* --------------------------------------------------------------------------
   Tokens (light)
   -------------------------------------------------------------------------- */
:root {
  /* Surfaces — theme-responsive (these flip in dark theme).
       Hue 192 (light) and 250 (dark) align with the DaisyUI airsign theme:
       light base ≈ #f8fafa (very faint teal cast pairs with the brand accent),
       dark base ≈ #3d4654 (slate). Old hue 240 was blue-violet — drifted from
       the DaisyUI tokens used in airsign-admin and the customer app. */
  --as-bg: oklch(99% 0.002 192);
  --as-bg-alt: oklch(97% 0.003 192);
  --as-bg-sunken: oklch(95% 0.004 192);
  /* Always-dark surfaces — for design-statement sections (cinema, footer)
       that should look the same regardless of user theme preference.
       Lifted slightly toward DaisyUI's slate dark base while still reading
       darker than the (newly lifted) `--as-bg` so dark cinema sections stay
       the deepest layer on the page. */
  --as-bg-dark: oklch(15% 0.018 250);
  --as-bg-dark-alt: oklch(20% 0.02 250);
  /* Always-light surfaces — for design-statement sections that should stay
       light regardless of user theme (e.g. .as-cinema--light pricing section,
       .as-prose-card blog reading panel). Without these, those sections would
       flip to dark in dark theme and the whole page would be one big dark slab. */
  --as-bg-paper: oklch(99% 0.002 192);
  --as-bg-paper-alt: oklch(97% 0.003 192);

  /* Ink — theme-responsive */
  --as-ink: oklch(18% 0.02 240);
  --as-ink-muted: oklch(48% 0.01 240);
  --as-ink-subtle: oklch(64% 0.008 240);
  /* Always-light ink (text on always-dark surfaces) */
  --as-ink-on-dark: oklch(97% 0.005 240);
  --as-ink-on-dark-muted: oklch(75% 0.01 240);
  --as-ink-on-dark-subtle: oklch(56% 0.012 240);
  /* Always-dark ink (text on always-light surfaces — the .as-bg-paper pair) */
  --as-ink-paper: oklch(18% 0.02 240);
  --as-ink-paper-muted: oklch(48% 0.01 240);

  /* Borders — theme-responsive. Light borders adopt the same hue 192 as
       light surfaces; dark and paper borders pick up the slate hue 250 / 192
       so hairline strokes don't read with a stale blue cast against the
       newly retuned base colours. */
  --as-border: oklch(92% 0.003 192);
  --as-border-strong: oklch(86% 0.004 192);
  /* Always-X borders — for the design-statement surfaces above */
  --as-border-on-dark: oklch(30% 0.016 250);
  --as-border-on-dark-strong: oklch(40% 0.02 250);
  --as-border-paper: oklch(92% 0.003 192);
  --as-border-paper-strong: oklch(86% 0.004 192);

  /* Cinema canvas — theme-responsive surface for `.as-cinema` sections.
     LIGHT theme defaults below: paper-light bg with dark ink, so a stack
     of cinema sections doesn't dominate the page with dark patches in
     light mode. The dark-theme override block (`[data-theme="airsign"]`)
     flips these to slate. Inner always-dark surfaces (`.as-story`,
     `.as-cta`, `.as-trust-strip`, `.as-footer`, hardcoded oklch cards)
     keep their own dark backgrounds — they read as deep feature panels
     against the paper cinema in light mode. */
  --as-cinema-bg: var(--as-bg-paper-alt);
  --as-cinema-ink: var(--as-ink-paper);
  --as-cinema-ink-muted: var(--as-ink-paper-muted);
  --as-cinema-pill-bg: oklch(0% 0 0 / 0.05);
  --as-cinema-pill-border: oklch(0% 0 0 / 0.1);
  --as-cinema-card-bg: var(--as-bg-paper);
  --as-cinema-card-bg-hover: oklch(96% 0.003 192);
  --as-cinema-card-border: var(--as-border-paper);
  --as-cinema-card-border-hover: var(--as-border-paper-strong);

  /* Accent — anchored to DaisyUI primary #0d9488 (teal-600).
       Hue 184 / chroma 0.10 maps to the same teal used in airsign-admin's
       DaisyUI theme so the public marketing site, the admin app, and the
       customer app share one brand tone. The decorative gradient/glow stops
       further down keep slightly higher chroma (0.13) for marketing punch. */
  --as-accent: oklch(58% 0.1 184);
  --as-accent-hover: oklch(52% 0.11 184);
  --as-accent-soft: oklch(95% 0.04 188);
  --as-accent-ink: oklch(40% 0.09 184);

  /* Status — anchored on DaisyUI airsign theme (#84cc16 / #fcd34d / #f87171)
       but shifted darker than the literal hex so they remain legible when
       used directly as a text colour (which marketing.css does in 5 places —
       savings panel, save-chip, discount banner, etc.). DaisyUI uses these
       as fill colours with a separate `*-content` token for text; we keep one
       token per status, hence the lower lightness. */
  --as-success: oklch(58% 0.18 130);
  --as-warning: oklch(70% 0.16 89);
  --as-error: oklch(60% 0.2 22);

  /* Status tints — fixed-light pill backgrounds + matching readable ink.
       Used by .as-callout--{info,success,warning,error} and the
       .as-table-row--tint-* utilities. INTENTIONALLY not theme-responsive:
       callouts and tinted table rows always read as light pills because
       they live inside paper-context surfaces (.as-prose-card, blog
       articles, light cinema sections) — flipping them dark in dark mode
       would invert their meaning and they'd disappear into the cinema bg.
       Hue + chroma matched to the corresponding --as-{success,warning,error}
       tokens so the border-left accent stripe and tint share a family. */
  --as-callout-info-bg: oklch(96% 0.04 188);
  --as-callout-info-ink: oklch(40% 0.09 184);
  --as-callout-success-bg: oklch(96% 0.06 130);
  --as-callout-success-ink: oklch(40% 0.13 130);
  --as-callout-warning-bg: oklch(97% 0.06 89);
  --as-callout-warning-ink: oklch(40% 0.13 89);
  --as-callout-error-bg: oklch(96% 0.05 22);
  --as-callout-error-ink: oklch(40% 0.15 22);

  /* Radius */
  --as-radius-sm: 6px;
  --as-radius-md: 10px;
  --as-radius-lg: 14px;
  --as-radius-xl: 20px;

  /* Typography */
  --as-font-display: 'Space Grotesk', 'Inter', system-ui, -apple-system, sans-serif;
  --as-font-body: 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --as-font-mono: ui-monospace, 'SF Mono', 'Roboto Mono', Menlo, monospace;

  /* Layout */
  --as-maxw-content: 72rem; /* 1152px */
  --as-maxw-prose: 42rem; /* 672px */
  --as-nav-h: 64px; /* shared between sticky navbar + subnav */

  /* Shadows — used sparingly, hairlines do most of the work */
  --as-shadow-sm: 0 1px 2px oklch(0% 0 0 / 0.04);
  --as-shadow-md: 0 4px 14px oklch(0% 0 0 / 0.06);
  --as-shadow-card: 0 1px 0 oklch(0% 0 0 / 0.02);
  --as-shadow-card-hover: 0 1px 0 oklch(0% 0 0 / 0.02), 0 0 0 1px var(--as-border-strong);
  --as-shadow-glow: 0 0 0 6px oklch(58% 0.13 184 / 0.1);
}

/* Dark theme — body bg lifted from 11% → 22% to half-step toward DaisyUI's
   #3d4654 slate. Cinema sections (.as-cinema below) stay markedly darker so
   the cinematic contrast is preserved against the new lighter body. Hue 240
   → 250 across all neutrals matches the DaisyUI airsign theme's slate cast. */
[data-theme='airsign'] {
  --as-bg: oklch(28% 0.019 250);
  --as-bg-alt: oklch(31% 0.02 250);
  --as-bg-sunken: oklch(25% 0.018 250);
  --as-ink: oklch(96% 0.005 250);
  --as-ink-muted: oklch(72% 0.01 250);
  --as-ink-subtle: oklch(52% 0.01 250);
  --as-border: oklch(32% 0.014 250);
  --as-border-strong: oklch(40% 0.018 250);
  /* Dark theme leans on DaisyUI's secondary (#2dd4bf, teal-400) for the
       accent — primary stays the same teal but secondary reads brighter
       against the dark base, which is what dark-mode interactive elements
       want. Soft surface uses the airsign theme's accent-content tone. */
  --as-accent: oklch(78% 0.13 184);
  --as-accent-hover: oklch(82% 0.13 184);
  --as-accent-soft: oklch(28% 0.06 184);
  --as-accent-ink: oklch(88% 0.1 184);
  /* Cinema canvas — flipped to slate-charcoal in dark theme so the
     cinema sections still read as the deeper feature surfaces against
     the body bg. Mirrors the lift we made earlier. */
  --as-cinema-bg: oklch(35% 0.018 250);
  --as-cinema-ink: oklch(97% 0.005 250);
  --as-cinema-ink-muted: oklch(75% 0.01 250);
  --as-cinema-pill-bg: oklch(100% 0 0 / 0.06);
  --as-cinema-pill-border: oklch(100% 0 0 / 0.12);
  --as-cinema-card-bg: oklch(28% 0.02 250 / 0.55);
  --as-cinema-card-bg-hover: oklch(32% 0.022 250 / 0.7);
  --as-cinema-card-border: oklch(100% 0 0 / 0.08);
  --as-cinema-card-border-hover: oklch(100% 0 0 / 0.18);
}

/* --------------------------------------------------------------------------
   Base reset (additive, Tailwind provides the rest)
   -------------------------------------------------------------------------- */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

body.as-page {
  background: var(--as-bg);
  color: var(--as-ink);
  font-family: var(--as-font-body);
  font-size: 0.9375rem; /* 15px */
  line-height: 1.6;
  font-feature-settings: 'ss01', 'cv11';
}

.as-page ::selection {
  background: var(--as-accent);
  color: white;
}

/* --------------------------------------------------------------------------
   Layout utilities
   -------------------------------------------------------------------------- */
.as-container {
  max-width: var(--as-maxw-content);
  margin-inline: auto;
  padding-inline: 1.5rem;
}
.as-container--prose {
  max-width: var(--as-maxw-prose);
  margin-inline: auto;
  padding-inline: 1.5rem;
}

/* --------------------------------------------------------------------------
   Typography — display scale
   --------------------------------------------------------------------------
   Canonical hierarchy:
     .as-display-mega  — hero only (clamp 2.75–5.75rem)
     .as-display-lg    — section headlines + sub-headlines + panel titles
                         (clamp 2–3.5rem; downsize via inline `style="font-size: clamp(...);"`
                          when a smaller panel title is wanted — see blog.html / demo.html)
     .as-cinema__lead  — one-line lead under section headlines
   `.as-display` (the middle tier) was retired in v2.8 — it overlapped tightly
   with `-lg` and all 4 sites that used it had inline font-size overrides
   anyway, so the class only ever contributed font-family/weight/color which
   `-lg` provides identically. Migrate any cached references to `-lg`.
   ---------------------------------------------------------------------- */

/* Section tag / eyebrow — small uppercase chip placed above section headlines.
   For inline pills inside body copy use `.as-pill` instead. */
.as-section-tag {
  display: inline-block;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--as-accent-ink);
  padding: 0.375rem 0.75rem;
  background: var(--as-accent-soft);
  border-radius: 999px;
  margin-bottom: 1.25rem;
}
/* Section tag rendered on a cinema canvas — name kept ("--on-dark") for
   back-compat with existing markup, but it now uses theme-responsive
   tokens so the tag stays readable when the cinema canvas flips to
   paper-light in light theme. */
.as-section-tag--on-dark {
  color: var(--as-accent-ink);
  background: var(--as-cinema-pill-bg);
  border: 1px solid var(--as-cinema-pill-border);
}

/* Body-text colour helpers — the canonical alternative to inline
   `style="color: oklch(...)"`. Use these on top of typography utilities so the
   tokens stay swappable when the theme changes. */
.as-text-ink {
  color: var(--as-ink);
}
.as-text-muted {
  color: var(--as-ink-muted);
}
/* Text helpers used directly on cinema canvas — flip with theme via cinema
   tokens. Class names kept ("on-dark") for back-compat with existing markup. */
.as-text-on-dark {
  color: var(--as-cinema-ink);
}
.as-text-on-dark-muted {
  color: var(--as-cinema-ink-muted);
}

/* Feature list — repeated check-bullet pattern used inside dark cinema sections.
   Replaces ad-hoc `<ul style="color: oklch(...)">` + `<i style="color: ...">`
   markup so colour tokens stay in CSS. Add `.as-feature-list--on-light` for the
   inverted use on light cinema sections. */
.as-feature-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.75rem;
  /* Theme-responsive — feature lists appear directly on the cinema
     canvas, so they follow the cinema-ink color which flips with theme. */
  color: var(--as-cinema-ink);
}
.as-feature-list > li {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
  line-height: 1.5;
}
.as-feature-list > li::before,
.as-feature-list__icon {
  flex-shrink: 0;
  margin-top: 0.15em;
  color: var(--as-accent);
  font-size: 1.125rem;
  line-height: 1;
}

/* Gradient text — subtle, only on display headings.
   IMPORTANT: variants use `background-image:` (not the `background:`
   shorthand) so the shared `background-clip: text` set above isn't reset.
   The shorthand `background:` resets every background longhand including
   clip, which would render the gradient as a solid block instead of
   clipping it to the text shape. */
.as-gradient-text,
.as-gradient-text--on-light,
.as-gradient-text--warm {
  background-clip: text;
  -webkit-background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
.as-gradient-text {
  background-image: linear-gradient(95deg, oklch(75% 0.13 184) 0%, oklch(92% 0.07 188) 100%);
}
.as-gradient-text--on-light {
  background-image: linear-gradient(95deg, var(--as-accent) 0%, oklch(48% 0.22 280) 100%);
}
.as-gradient-text--warm {
  background-image: linear-gradient(95deg, oklch(70% 0.17 60) 0%, oklch(60% 0.22 30) 100%);
}

/* --------------------------------------------------------------------------
   Pills / badges
   --------------------------------------------------------------------------
   Canonical section frame is `.as-cinema` — the legacy `.as-hero` /
   `.as-hero--light` classes were retired in 2026-04.
   ---------------------------------------------------------------------- */
.as-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.3125rem 0.75rem;
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1;
  color: var(--as-accent-ink);
  background: var(--as-accent-soft);
  border: 1px solid transparent;
  border-radius: 999px;
  white-space: nowrap;
}
/* Pill rendered on a cinema canvas — name kept ("--on-dark") for back-compat
   with existing markup. Uses theme-responsive cinema-pill tokens so the pill
   reads correctly in both themes after .as-cinema flipped paper-light. */
.as-pill--on-dark {
  color: var(--as-accent-ink);
  background: var(--as-cinema-pill-bg);
  border-color: var(--as-cinema-pill-border);
}
.as-pill--dot::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--as-accent);
  box-shadow: 0 0 0 3px oklch(58% 0.13 184 / 0.25);
}
.as-pill--on-dark.as-pill--dot::before {
  background: oklch(80% 0.13 184);
  box-shadow: 0 0 0 3px oklch(80% 0.13 184 / 0.22);
}

/* Full-width list row (replaces outline badges in long feature checklists) */
.as-pill--row {
  display: flex;
  width: 100%;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 0.75rem;
  font-size: 0.875rem;
  font-weight: 500;
  line-height: 1.3;
  border-radius: var(--as-radius-md);
  border: 1px solid var(--as-border);
  background: color-mix(in oklch, var(--as-bg) 88%, var(--as-ink));
  color: var(--as-ink);
}
.as-cinema .card.as-card .as-pill--row,
.as-cinema .as-pill--row {
  border-color: var(--as-border-on-dark);
  background: oklch(100% 0 0 / 0.04);
  color: var(--as-ink-on-dark);
}

/* Hairline separator — prefer over DaisyUI .divider in marketing card bodies */
hr.as-hairline,
.as-hairline[role='separator'] {
  display: block;
  width: 100%;
  height: 0;
  margin: 1rem 0;
  border: 0;
  border-top: 1px solid var(--as-border-on-dark);
  opacity: 0.45;
}
.as-cinema--light hr.as-hairline,
.as-cinema--light .as-hairline[role='separator'] {
  /* Paper-stable border so the hairline stays a pale rule on the light section,
       even in dark theme (where var(--as-border) flips to a dark line). */
  border-top-color: var(--as-border-paper);
  opacity: 0.65;
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.as-btn-primary,
.btn.as-btn-primary {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6875rem 1.125rem;
  font-family: var(--as-font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1;
  color: white !important;
  background: var(--as-accent);
  border: 1px solid var(--as-accent);
  border-radius: var(--as-radius-md);
  transition:
    background 150ms ease,
    border-color 150ms ease,
    transform 150ms ease;
  text-decoration: none;
  box-shadow: var(--as-shadow-sm);
}
.as-btn-primary:hover,
.btn.as-btn-primary:hover {
  background: var(--as-accent-hover);
  border-color: var(--as-accent-hover);
}
.as-btn-primary:active {
  transform: translateY(1px);
}

.btn.as-btn-primary.btn-lg {
  padding: 0.8125rem 1.375rem;
  font-size: 1rem;
}

.as-btn-ghost-on-dark,
.btn.as-btn-ghost-on-dark {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6875rem 1.125rem;
  font-family: var(--as-font-body);
  font-size: 0.9375rem;
  font-weight: 600;
  line-height: 1;
  /* Class name kept for back-compat ("on-dark") but uses theme-responsive
     cinema tokens so the text + border stay visible whether the cinema
     canvas is paper-light (light theme) or slate (dark theme). */
  color: var(--as-cinema-ink) !important;
  background: transparent;
  border: 1px solid var(--as-cinema-pill-border);
  border-radius: var(--as-radius-md);
  transition:
    background 150ms ease,
    border-color 150ms ease;
  text-decoration: none;
}
.as-btn-ghost-on-dark:hover,
.btn.as-btn-ghost-on-dark:hover {
  background: var(--as-cinema-pill-bg);
  border-color: var(--as-cinema-ink-muted);
}
.btn.as-btn-ghost-on-dark.btn-lg {
  padding: 0.8125rem 1.375rem;
  font-size: 1rem;
}

/* Light-context ghost */
.as-btn-ghost {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.6875rem 1.125rem;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--as-ink) !important;
  background: transparent;
  border: 1px solid var(--as-border-strong);
  border-radius: var(--as-radius-md);
  text-decoration: none;
  transition:
    background 150ms ease,
    border-color 150ms ease;
}
.as-btn-ghost:hover {
  background: var(--as-bg-alt);
  border-color: var(--as-ink-subtle);
}

/* --------------------------------------------------------------------------
   Cards / panels
   -------------------------------------------------------------------------- */
.as-card {
  background: var(--as-bg);
  border: 1px solid var(--as-border);
  border-radius: var(--as-radius-lg);
  padding: 1.5rem;
  transition:
    border-color 150ms ease,
    transform 150ms ease;
}
.as-card:hover {
  border-color: var(--as-border-strong);
}
/* Featured modifier — for the one card per grid that should anchor attention.
   Stronger accent border + a subtle accent-tinted ring instead of a heavy
   shadow (the design system avoids those). Combine with `.as-card`. */
.as-card--featured {
  border-color: var(--as-accent);
  box-shadow: 0 0 0 1px var(--as-accent);
}
.as-card--featured:hover {
  border-color: var(--as-accent-hover);
}
.as-cinema .as-card--featured,
.as-cinema .card.as-card--featured {
  border-color: oklch(58% 0.13 184 / 0.55);
  box-shadow: 0 0 0 1px oklch(58% 0.13 184 / 0.45);
}

.as-panel {
  background: var(--as-bg-alt);
  border: 1px solid var(--as-border);
  border-radius: var(--as-radius-lg);
  padding: clamp(1.25rem, 3vw, 2rem);
}

.as-glass {
  /* Glass uses cinema-pill tokens so it works as a translucent panel on
     either a light cinema (subtle dark veil) or a dark cinema (subtle
     light veil). Without theme-responsive tokens this would be a near-
     white panel on a near-white light cinema → invisible. */
  background: var(--as-cinema-pill-bg);
  border: 1px solid var(--as-cinema-pill-border);
  border-radius: var(--as-radius-lg);
  backdrop-filter: blur(8px);
  padding: 1.5rem;
}

/* Feature card — BEM elements, paired with `.as-card` or `.as-panel` wrapper */
.as-feature__icon,
.as-icon-chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: var(--as-radius-sm);
  background: var(--as-accent-soft);
  color: var(--as-accent-ink);
}
.as-feature__icon {
  font-size: 1.125rem;
  margin-bottom: 1rem;
}
.as-feature__title {
  font-family: var(--as-font-display);
  font-size: 1.0625rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: 0.5rem;
  color: var(--as-ink);
}
.as-feature__body {
  font-size: 0.9375rem;
  color: var(--as-ink-muted);
  line-height: 1.55;
  margin-bottom: 1rem;
}

/* Icon chip (contact cards, hero media tape) */
.as-icon-chip {
  border: 1px solid transparent;
  font-size: 1rem;
  flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   Category header (features.html numbered sections)
   -------------------------------------------------------------------------- */
.as-category-header {
  display: flex;
  align-items: baseline;
  gap: 1rem;
  padding-bottom: 1rem;
  border-bottom: 1px solid var(--as-border);
  margin-bottom: 2.5rem;
}
.as-category-header__number {
  font-family: var(--as-font-mono);
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--as-ink-subtle);
  letter-spacing: 0.05em;
}
.as-category-header__title {
  font-family: var(--as-font-display);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--as-ink);
}

/* --------------------------------------------------------------------------
   Misc primitives
   --------------------------------------------------------------------------
   Canonical pricing card is `.as-pricing-tile` (cinema homepage) or
   `.as-calc-tile` (calc breakdown). The legacy `.as-plan*` ecosystem was
   retired in 2026-04. `.as-quote` (legacy padded blockquote) was retired
   alongside; use `.as-callout` for inline notes or build inline as needed.
   ---------------------------------------------------------------------- */
.as-readmore {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--as-accent);
  text-decoration: none;
  transition: gap 150ms ease;
}
.as-readmore:hover {
  gap: 0.625rem;
}

.as-steps {
  list-style: none;
  margin: 0;
  padding: 0;
  counter-reset: as-step;
  display: grid;
  gap: 1rem;
}
.as-steps li {
  counter-increment: as-step;
  padding-left: 2.75rem;
  position: relative;
  color: var(--as-ink-muted);
}
.as-steps li::before {
  content: counter(as-step, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 0;
  width: 2rem;
  height: 2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--as-font-mono);
  font-size: 0.75rem;
  font-weight: 500;
  color: var(--as-accent-ink);
  background: var(--as-accent-soft);
  border-radius: var(--as-radius-sm);
}

.as-cta {
  background: var(--as-bg-dark);
  color: var(--as-ink-on-dark);
  padding-block: clamp(4rem, 7vw, 6.5rem);
  position: relative;
  isolation: isolate;
  overflow: hidden;
}
.as-cta::before {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse 70% 60% at 50% 0%,
    oklch(35% 0.13 184 / 0.5) 0%,
    transparent 65%
  );
  z-index: -1;
}
.as-cta h2,
.as-cta h3 {
  color: var(--as-ink-on-dark);
}

/* --------------------------------------------------------------------------
   Form elements
   -------------------------------------------------------------------------- */
.as-field {
  display: grid;
  gap: 0.375rem;
  margin-bottom: 1rem;
}
.as-field label,
.as-label {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--as-ink);
  letter-spacing: 0.01em;
}
.as-input,
.as-field input[type='text'],
.as-field input[type='email'],
.as-field input[type='tel'],
.as-field input[type='number'],
.as-field select,
.as-field textarea {
  width: 100%;
  padding: 0.625rem 0.75rem;
  font-family: var(--as-font-body);
  font-size: 0.9375rem;
  color: var(--as-ink);
  background: var(--as-bg);
  border: 1px solid var(--as-border-strong);
  border-radius: var(--as-radius-md);
  transition:
    border-color 150ms ease,
    box-shadow 150ms ease;
}
.as-input:focus,
.as-field input:focus,
.as-field select:focus,
.as-field textarea:focus {
  outline: none;
  border-color: var(--as-accent);
  box-shadow: 0 0 0 3px oklch(58% 0.13 184 / 0.15);
}

/* --------------------------------------------------------------------------
   Navbar — override DaisyUI for a thinner, sharper nav
   -------------------------------------------------------------------------- */
body.as-page > nav.navbar,
.as-nav {
  min-height: var(--as-nav-h);
  background: oklch(100% 0 0 / 0.78) !important;
  border-bottom: 1px solid var(--as-border);
  box-shadow: none !important;
  backdrop-filter: saturate(1.4) blur(10px);
  -webkit-backdrop-filter: saturate(1.4) blur(10px);
  padding-inline: 1rem;
}
[data-theme='airsign'] body.as-page > nav.navbar,
[data-theme='airsign'] .as-nav {
  background: oklch(12% 0.018 250 / 0.78) !important;
  border-bottom-color: var(--as-border-on-dark);
}
body.as-page > nav.navbar .menu-horizontal > li > a {
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--as-ink-muted);
  padding-inline: 0.875rem;
  border-radius: var(--as-radius-sm);
}
body.as-page > nav.navbar .menu-horizontal > li > a:hover {
  background: var(--as-bg-alt);
  color: var(--as-ink);
}
/* Active nav link — current page indicator. Specificity matches the base
   selector above so the active style wins over the muted default colour. */
body.as-page > nav.navbar .menu-horizontal > li > a.active,
body.as-page > nav.navbar .menu-horizontal > li > a.menu-active {
  color: var(--as-ink);
  background: transparent;
  position: relative;
  font-weight: 600;
}
body.as-page > nav.navbar .menu-horizontal > li > a.active::after,
body.as-page > nav.navbar .menu-horizontal > li > a.menu-active::after {
  content: '';
  position: absolute;
  left: 0.875rem;
  right: 0.875rem;
  bottom: 0.125rem;
  height: 2px;
  background: var(--as-accent);
  border-radius: 2px;
}
body.as-page > nav.navbar .menu-horizontal > li > a.active:hover,
body.as-page > nav.navbar .menu-horizontal > li > a.menu-active:hover {
  background: var(--as-bg-alt);
}
/* Mobile dropdown — same active treatment, no underline (vertical layout) */
body.as-page > nav.navbar .dropdown-content li > a.active,
body.as-page > nav.navbar .dropdown-content li > a.menu-active {
  color: var(--as-accent);
  background: var(--as-accent-soft);
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   Category header supplemental body copy
   -------------------------------------------------------------------------- */
.as-category-header__body {
  margin-top: 0.375rem;
  font-size: 0.9375rem;
  color: var(--as-ink-muted);
  max-width: 46rem;
}

/* --------------------------------------------------------------------------
   Icon chip variants
   -------------------------------------------------------------------------- */
.as-icon-chip--lg {
  width: 44px;
  height: 44px;
  font-size: 1.25rem;
}
.as-icon-chip--hero {
  width: 52px;
  height: 52px;
  font-size: 1.5rem;
  border-radius: var(--as-radius-md);
}
/* Success-tinted chip — pale lime fill matching the rest of the success
   surfaces (.as-callout--success, .as-save-chip, .as-discount-banner).
   Pulls from --as-callout-success-bg so the whole success family stays
   in lockstep; the icon glyph still picks up `.as-icon-success`'s
   `color: var(--as-success)`. */
.as-icon-chip--success {
  background: var(--as-callout-success-bg);
}

.as-icon-accent {
  color: var(--as-accent);
}
.as-icon-success {
  color: var(--as-success);
}

/* --------------------------------------------------------------------------
   Pricing calculator — hero, breakdown, side grids (pricing.html + index.html)
   -------------------------------------------------------------------------- */
.as-calc-tile {
  background: var(--as-bg);
  border: 1px solid var(--as-border);
  border-radius: var(--as-radius-lg);
  padding: 1.25rem;
  display: grid;
  gap: 0.5rem;
}
.as-calc-tile--brand {
  background: var(--as-accent-soft);
  border-color: oklch(58% 0.13 184 / 0.25);
}
.as-calc-tile__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  font-size: 0.8125rem;
  color: var(--as-ink-muted);
}
.as-calc-tile--brand .as-calc-tile__head {
  color: var(--as-accent-ink);
}
.as-calc-tile__label {
  font-size: 0.8125rem;
  color: var(--as-ink-muted);
  font-weight: 500;
}
.as-calc-tile__hero {
  display: flex;
  align-items: baseline;
  gap: 0.375rem;
  flex-wrap: wrap;
}
.as-calc-tile__amount {
  font-family: var(--as-font-display);
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
  color: var(--as-ink);
}
.as-calc-tile--brand .as-calc-tile__amount {
  color: var(--as-accent-ink);
}
.as-calc-tile__per {
  font-size: 0.8125rem;
  color: var(--as-ink-muted);
}
.as-calc-tile__value {
  font-family: var(--as-font-display);
  font-size: 1.375rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--as-ink);
}
.as-calc-tile__meta {
  font-size: 0.75rem;
  color: var(--as-ink-subtle);
}
.as-calc-tile__badge {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.1875rem 0.5rem;
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--as-success);
  background: var(--as-callout-success-bg);
  border-radius: var(--as-radius-sm);
}
.as-calc-tile__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.75rem;
  margin-top: 0.375rem;
  padding-top: 0.625rem;
  border-top: 1px dashed var(--as-border);
}
.as-calc-tile__total-label {
  font-size: 0.8125rem;
  color: var(--as-ink-muted);
}
.as-calc-tile__total-value {
  font-family: var(--as-font-display);
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--as-ink);
}

.as-calc-hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem 2rem;
  padding: clamp(1.5rem, 3vw, 2rem);
  background: var(--as-bg);
  border: 1px solid var(--as-border);
  border-radius: var(--as-radius-xl);
}
@media (min-width: 800px) {
  .as-calc-hero {
    grid-template-columns: 3fr 2fr;
    align-items: center;
  }
}
.as-calc-hero__left {
  display: grid;
  gap: 0.5rem;
}
.as-calc-hero__right {
  display: grid;
  gap: 0.375rem;
  padding: 1rem;
  background: var(--as-accent-soft);
  border-radius: var(--as-radius-md);
}
.as-calc-hero__label {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--as-ink-muted);
}
.as-calc-hero__price-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 0.375rem 0.625rem;
}
.as-calc-hero__price {
  font-family: var(--as-font-display);
  font-size: clamp(2.25rem, 5vw, 3.25rem);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1;
  color: var(--as-ink);
}
.as-calc-hero__currency,
.as-calc-hero__unit {
  font-size: 0.9375rem;
  color: var(--as-ink-muted);
}
.as-calc-hero__original {
  font-size: 0.9375rem;
  color: var(--as-ink-subtle);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}
.as-calc-hero__savings-annual {
  font-family: var(--as-font-display);
  font-size: 1.375rem;
  font-weight: 600;
  color: var(--as-success);
  letter-spacing: -0.015em;
}
.as-calc-hero__savings-meta {
  font-size: 0.8125rem;
  color: var(--as-ink-muted);
}

.as-calc-breakdown {
  margin-top: 1.5rem;
  padding-top: 1.5rem;
  border-top: 1px solid var(--as-border);
}
.as-calc-breakdown__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.75rem;
}
@media (min-width: 640px) {
  .as-calc-breakdown__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 900px) {
  .as-calc-breakdown__grid {
    grid-template-columns: repeat(4, 1fr);
  }
}

.as-calc-side-grid {
  display: grid;
  gap: 0.75rem;
}
.as-calc-side-grid--two {
  grid-template-columns: repeat(2, 1fr);
}

.as-calc-results {
  margin-top: 1.5rem;
  padding: 1rem 1.25rem;
  background: var(--as-bg-alt);
  border: 1px solid var(--as-border);
  border-radius: var(--as-radius-md);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.as-save-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.25rem 0.625rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--as-success);
  background: var(--as-callout-success-bg);
  border-radius: 999px;
}

.as-discount-banner {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.75rem 1rem;
  margin-top: 1rem;
  background: var(--as-callout-success-bg);
  border: 1px solid oklch(85% 0.1 130);
  border-radius: var(--as-radius-md);
  color: var(--as-callout-success-ink);
  font-size: 0.875rem;
}
.as-discount-banner i {
  color: var(--as-success);
  font-size: 1.125rem;
  flex-shrink: 0;
}

/* --------------------------------------------------------------------------
   Blog — article cards, article table, callouts, stat value
   -------------------------------------------------------------------------- */
.as-article-card {
  background: var(--as-bg);
  border: 1px solid var(--as-border);
  border-radius: var(--as-radius-lg);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
  transition:
    border-color 150ms ease,
    transform 150ms ease;
  text-decoration: none;
  color: inherit;
}
.as-article-card:hover {
  border-color: var(--as-border-strong);
  transform: translateY(-1px);
}
.as-article-card--tinted {
  background: var(--as-bg-alt);
}
.as-article-card h2,
.as-article-card h3 {
  font-family: var(--as-font-display);
  font-size: 1.125rem;
  font-weight: 600;
  color: var(--as-ink);
  letter-spacing: -0.015em;
}
.as-article-card p {
  font-size: 0.9375rem;
  color: var(--as-ink-muted);
  line-height: 1.55;
}
.as-article-card time {
  font-size: 0.75rem;
  font-family: var(--as-font-mono);
  color: var(--as-ink-subtle);
  letter-spacing: 0.02em;
}

.as-article-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
  margin: 1.5rem 0;
}
/* `as-article-table` is always inside a blog `.as-prose-card` (paper context),
   so use paper tokens — otherwise the table inverts to dark in dark theme and
   the row borders disappear into the dark prose-card bg (which itself doesn't
   invert because it uses paper tokens). */
.as-article-table th,
.as-article-table td {
  padding: 0.75rem 0.875rem;
  text-align: left;
  border-bottom: 1px solid var(--as-border-paper);
  vertical-align: top;
  color: var(--as-ink-paper);
}
.as-article-table th {
  font-weight: 600;
  color: var(--as-ink-paper);
  background: var(--as-bg-paper-alt);
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
}
.as-article-table tr:last-child td {
  border-bottom: 0;
}

/* Callouts always render on light surfaces (.as-prose-card paper, or
   .as-cinema dark-on-dark which wants a light pill for contrast). Use the
   always-light paper tokens so the callout doesn't darken in dark theme.
   Status-modifier backgrounds below are hardcoded light tints for the same
   reason — they're meant to be light pills regardless of user theme. */
.as-callout {
  padding: 1rem 1.125rem;
  margin: 1.25rem 0;
  background: var(--as-bg-paper-alt);
  border: 1px solid var(--as-border-paper);
  border-left: 3px solid var(--as-accent);
  border-radius: var(--as-radius-md);
  font-size: 0.9375rem;
  color: var(--as-ink-paper);
}
.as-callout p {
  margin: 0;
}
.as-callout p + p {
  margin-top: 0.5rem;
}
/* Status-tinted callouts — fixed-light tints regardless of theme (see the
   --as-callout-*-bg comment in 01-tokens-base.css for the why). The
   border-left accent uses the matching status text token so the family
   is consistent across the four variants. */
.as-callout--info {
  border-left-color: var(--as-accent);
  background: var(--as-callout-info-bg);
}
.as-callout--success {
  border-left-color: var(--as-success);
  background: var(--as-callout-success-bg);
}
.as-callout--warning {
  border-left-color: var(--as-warning);
  background: var(--as-callout-warning-bg);
}
.as-callout--error {
  border-left-color: var(--as-error);
  background: var(--as-callout-error-bg);
}
/* Larger variant — for block-level callouts that need more breathing room. */
.as-callout--lg {
  padding: 1.5rem 1.75rem;
  margin: 2rem 0;
  border-left-width: 4px;
}

/* Status-tint utility — applies the callout pill background to any element
   (table row, div panel, stats block) so blog-prose markup can express
   "this is the recommended option" / "this is the wrong option" with a
   class instead of an inline style. Pair with `.as-tint-*-ink` for cells
   that also need readable colored text (e.g. the bold "TOTALT" row in
   ROI tables). Replaces inline `style="background: oklch(...)"` patterns. */
.as-tint-success {
  background: var(--as-callout-success-bg);
}
.as-tint-success-ink {
  color: var(--as-callout-success-ink);
}
.as-tint-error {
  background: var(--as-callout-error-bg);
}
.as-tint-error-ink {
  color: var(--as-callout-error-ink);
}

/* Inline stat number used inside blog prose-card (paper context). */
.as-stat-value {
  font-family: var(--as-font-display);
  font-size: clamp(1.5rem, 2.5vw, 2rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.05;
  color: var(--as-ink-paper);
}

/* ============================================================================
   Cinema set — Apple-TV-style sections (homepage canonical)
   ============================================================================
   Style north star: apple.com/se/apple-tv. Black canvas, large display
   type, full-bleed visuals, one declarative line per section, restrained CTAs.
   ========================================================================== */

/* Mega display headline — used once or twice per cinema page */
.as-display-mega {
  font-family: var(--as-font-display);
  font-weight: 600;
  font-size: clamp(2.75rem, 7vw, 5.75rem);
  line-height: 0.98;
  letter-spacing: -0.035em;
  color: var(--as-ink);
}
.as-cinema .as-display-mega {
  color: var(--as-cinema-ink);
}
/* Paper context — always-dark heading, no theme flip. */
.as-cinema--light .as-display-mega {
  color: var(--as-ink-paper);
}

.as-display-lg {
  font-family: var(--as-font-display);
  font-weight: 600;
  font-size: clamp(2rem, 4.5vw, 3.5rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--as-ink);
}
.as-cinema .as-display-lg {
  color: var(--as-cinema-ink);
}
.as-cinema--light .as-display-lg {
  color: var(--as-ink-paper);
}

/* Panel-title size — smaller than a cinema headline. Use on `.as-display-lg`
   inside in-panel headers like "Fyll i dina uppgifter" (demo form) or
   "Utforska efter ämne" (blog category panel). Replaces inline
   `style="font-size: clamp(1.5rem, 2.5vw, 1.875rem);"` overrides that
   appeared verbatim in demo.html and blog.html. */
.as-display-lg--panel {
  font-size: clamp(1.5rem, 2.5vw, 1.875rem);
}
/* Small variant — half-step larger than `--panel`. Use on in-context section
   headlines that sit inside a paper card (e.g. "Vad ingår i priset?" on
   the pricing page) where the full `.as-display-lg` would dominate the
   surrounding body copy. Replaces an inline `font-size: clamp(...)` override
   that lived in pricing.astro. */
.as-display-lg--sm {
  font-size: clamp(1.75rem, 3vw, 2.25rem);
}

/* Numeric mega — for big standalone digits that aren't a sentence
   (e.g. the 404 glyph on the not-found page). Uses the display family
   like the rest of the ladder but with line-height: 1 and a deeper
   clamp than `.as-display-mega` so the digits read as a graphic, not
   a heading. Replaces an inline `font-size: clamp(5rem, 14vw, 9rem)`
   override in 404.astro. */
.as-display-num {
  font-family: var(--as-font-display);
  font-weight: 600;
  font-size: clamp(5rem, 14vw, 9rem);
  line-height: 1;
  letter-spacing: -0.035em;
  color: var(--as-ink);
}
.as-cinema .as-display-num {
  color: var(--as-cinema-ink);
}
.as-cinema--light .as-display-num {
  color: var(--as-ink-paper);
}

/* Full-bleed cinema section — slate-charcoal canvas, edge-to-edge content
   allowed. Lifted from the original near-black (#000 → 8%) up to 22% so
   the page reads as on-brand slate rather than a stack of black voids in
   light theme. Matches the dark-theme body bg, which means cinema sections
   read as a continuous slate surface in dark mode and as mid-slate
   "feature panels" against the light body in light mode. The original
   "Apple-TV cinema" depth has been retired in favor of a more brand-
   coherent slate that matches the airsign DaisyUI base. */
.as-cinema {
  /* Theme-responsive surface via `--as-cinema-*` tokens defined in :root +
     [data-theme="airsign"]. In light theme cinema is paper-light so a stack
     of cinema sections doesn't dominate the page with dark patches; in dark
     theme cinema flips to slate-charcoal and the page reads as a continuous
     slate surface. */
  background: var(--as-cinema-bg);
  color: var(--as-cinema-ink);
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding-block: clamp(4rem, 8vw, 7.5rem);
}
.as-cinema--alt {
  /* Slight tint shift from --as-cinema-bg so adjacent cinema sections still
     read as a rhythm break. In light theme: a touch darker paper; in dark
     theme: a touch lighter slate. */
  background: color-mix(in oklch, var(--as-cinema-bg) 92%, var(--as-cinema-ink) 8%);
}
/* `.as-cinema--light` is a design-statement light section — pricing on the
   homepage, prose body on blog articles. Use the always-light `--as-bg-paper`
   tokens (not the theme-responsive `--as-bg`) so the section stays light even
   when the user is on dark theme. Otherwise the whole page reads as one dark
   slab in dark mode. */
.as-cinema--light {
  background: var(--as-bg-paper);
  color: var(--as-ink-paper);
}
/* Tighter cinema — used for secondary bands (e.g. blog category strip) where
   the full cinematic 5rem→9rem block would feel oversized. */
.as-cinema--tight {
  padding-block: clamp(2.5rem, 5vw, 4rem);
}

/* Vivid hero — full-bleed background image + dark scrim + animated teal
   pulse, used on the homepage hero only so it stands apart from the
   product-composite hero used on every other landing page. The image is
   desaturated and dimmed so the headline still anchors the composition;
   the pulse adds a subtle "live" feel without breaking the brand restraint
   the rest of the cinema sections follow. */
.as-cinema.as-hero-vivid {
  /* Vivid hero is ALWAYS-DARK because the bg image + scrim form a dark
     atmosphere regardless of theme. Redirect cinema tokens here so the
     headline + lead + pill stay light-on-dark even when other cinema
     sections flip to paper-light in light theme. */
  --as-cinema-ink: var(--as-ink-on-dark);
  --as-cinema-ink-muted: var(--as-ink-on-dark-muted);
  --as-cinema-pill-bg: oklch(100% 0 0 / 0.06);
  --as-cinema-pill-border: oklch(100% 0 0 / 0.12);
}
.as-hero-vivid__bg {
  position: absolute;
  inset: 0;
  z-index: -3;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Subject-first: the photograph drives the atmosphere. Scrim + pulse
     layers carry the rest of the contrast/brand work — no need to crush
     the image. */
  filter: brightness(0.82) saturate(0.95);
}
.as-hero-vivid__scrim {
  position: absolute;
  inset: 0;
  z-index: -2;
  pointer-events: none;
  /* Lightened vignette + bottom-weighted backing. Center stays clear so
     the photo reads; edges and bottom carry just enough darkness for the
     headline, lead, CTAs and stat row to clear contrast. */
  background:
    radial-gradient(
      ellipse 70% 60% at 50% 40%,
      transparent 0%,
      oklch(20% 0.018 250 / 0.28) 70%,
      oklch(12% 0.018 250 / 0.62) 100%
    ),
    linear-gradient(180deg, oklch(20% 0.018 250 / 0.12) 0%, oklch(20% 0.018 250 / 0.45) 100%);
}
/* Animated teal accent pulse — a slow ~8s breathing radial that ties the
   bg back to the brand accent (`--as-accent`). Sits above the scrim so
   it tints whatever shows through. Honors prefers-reduced-motion. */
.as-hero-vivid__pulse {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(
    ellipse 55% 35% at 50% 65%,
    oklch(58% 0.13 184 / 0.28) 0%,
    transparent 65%
  );
  animation: as-hero-pulse 8s ease-in-out infinite;
  will-change: opacity, transform;
}
@keyframes as-hero-pulse {
  0%,
  100% {
    opacity: 0.55;
    transform: scale(1);
  }
  50% {
    opacity: 1;
    transform: scale(1.06);
  }
}
@media (prefers-reduced-motion: reduce) {
  .as-hero-vivid__pulse {
    animation: none;
    opacity: 0.7;
    transform: none;
  }
}
.as-cinema h1,
.as-cinema h2,
.as-cinema h3 {
  color: var(--as-cinema-ink);
}
.as-cinema--light h1,
.as-cinema--light h2,
.as-cinema--light h3 {
  color: var(--as-ink-paper);
}
.as-cinema__lead {
  font-size: clamp(1.0625rem, 1.6vw, 1.375rem);
  line-height: 1.4;
  color: var(--as-cinema-ink-muted);
  max-width: 48rem;
  margin-inline: auto;
}
.as-cinema--light .as-cinema__lead {
  color: var(--as-ink-paper-muted);
}

/* Paper-context overrides for theme-responsive components that appear inside
   always-light surfaces (`.as-cinema--light` and `.as-prose-card`). Without
   these, the components would invert their bg/ink in dark theme and become
   illegible against the always-light parent — e.g. a dark-tinted accent pill
   on a bright paper page. Tokens are hardcoded to the light-theme values. */
.as-cinema--light .as-section-tag,
.as-prose-card .as-section-tag,
.as-cinema--light .as-pill:not(.as-pill--on-dark),
.as-prose-card .as-pill:not(.as-pill--on-dark) {
  color: oklch(40% 0.09 184); /* always-dark accent ink */
  background: oklch(96% 0.04 188); /* always-pale accent soft */
}

/* Paper-context article cards — same goal as the pill/tag overrides above.
   `.as-article-card` uses theme-responsive `--as-bg` / `--as-ink`, so in
   dark theme it flips dark-on-dark even though the surrounding section is
   forced paper-light. Pin to paper tokens so blog idea grids (e.g.
   innehallsideer-digital-skylt) render consistently regardless of theme. */
.as-cinema--light .as-article-card,
.as-prose-card .as-article-card {
  background: var(--as-bg-paper);
  border-color: var(--as-border-paper);
  color: var(--as-ink-paper);
}
.as-cinema--light .as-article-card--tinted,
.as-prose-card .as-article-card--tinted {
  background: oklch(97% 0.005 192);
}
.as-cinema--light .as-article-card:hover,
.as-prose-card .as-article-card:hover {
  border-color: var(--as-border-paper-strong);
}
.as-cinema--light .as-article-card h2,
.as-cinema--light .as-article-card h3,
.as-cinema--light .as-article-card .card-title,
.as-prose-card .as-article-card h2,
.as-prose-card .as-article-card h3,
.as-prose-card .as-article-card .card-title {
  color: var(--as-ink-paper);
}
.as-cinema--light .as-article-card p,
.as-cinema--light .as-article-card li,
.as-prose-card .as-article-card p,
.as-prose-card .as-article-card li {
  color: var(--as-ink-paper-muted);
}
.as-cinema--light .as-article-card .opacity-70,
.as-cinema--light .as-article-card .opacity-80,
.as-prose-card .as-article-card .opacity-70,
.as-prose-card .as-article-card .opacity-80 {
  color: var(--as-ink-paper-muted);
  opacity: 1;
}

/* Paper-context generic .as-card — same intent as .as-article-card override.
   .as-card uses --as-bg / --as-border / --as-ink (theme-responsive), and the
   .as-cinema .as-card cinema-card-token override doesn't pin to paper inside
   .as-cinema--light because cinema-card tokens themselves flip in dark theme.
   Force paper tokens so plain .as-card markup stays light-on-paper everywhere. */
.as-cinema--light .as-card,
.as-cinema--light .card.as-card,
.as-prose-card .as-card,
.as-prose-card .card.as-card {
  background: var(--as-bg-paper);
  border-color: var(--as-border-paper);
  color: var(--as-ink-paper);
}
.as-cinema--light .as-card:hover,
.as-cinema--light .card.as-card:hover,
.as-prose-card .as-card:hover,
.as-prose-card .card.as-card:hover {
  border-color: var(--as-border-paper-strong);
  background: oklch(97% 0.003 192);
}
.as-cinema--light .as-card h2,
.as-cinema--light .as-card h3,
.as-cinema--light .as-card .card-title,
.as-prose-card .as-card h2,
.as-prose-card .as-card h3,
.as-prose-card .as-card .card-title {
  color: var(--as-ink-paper);
}
.as-cinema--light .as-card p,
.as-cinema--light .as-card ul,
.as-cinema--light .as-card li,
.as-prose-card .as-card p,
.as-prose-card .as-card ul,
.as-prose-card .as-card li {
  color: var(--as-ink-paper-muted);
}
.as-cinema--light .as-card .opacity-70,
.as-cinema--light .as-card .opacity-80,
.as-prose-card .as-card .opacity-70,
.as-prose-card .as-card .opacity-80 {
  color: var(--as-ink-paper-muted);
  opacity: 1;
}

/* Paper-context icon-accent + accent-soft surfaces.
   --as-accent-soft flips dark teal in dark theme (chroma:0.06 lightness:28%),
   which renders unreadable on a paper page. Pin to the always-light pale-teal
   so accent pills/icons stay legible inside cinema--light + prose-card. */
.as-cinema--light .as-icon-accent,
.as-cinema--light .as-icon-chip,
.as-cinema--light .as-feature__icon,
.as-prose-card .as-icon-accent,
.as-prose-card .as-icon-chip,
.as-prose-card .as-feature__icon {
  background: oklch(95% 0.04 188);
  color: oklch(40% 0.09 184);
  border-color: oklch(88% 0.04 188);
}

/* Paper-context callout border-accent.
   .as-callout --info uses var(--as-accent) for its left border, which
   brightens to oklch(78% 0.13 184) in dark theme. That's still readable
   but visually inconsistent with the always-paper interior. Pin to the
   always-dark accent-ink for visual continuity. */
.as-cinema--light .as-callout,
.as-prose-card .as-callout {
  border-color: var(--as-border-paper);
}
.as-cinema--light .as-callout--info,
.as-prose-card .as-callout--info {
  border-left-color: oklch(58% 0.1 184);
}

/* Paper-context DaisyUI base components.
   DaisyUI's .stat / .stats / .alert / plain .card use --b1/--b2/--bc which
   are the user's selected DaisyUI theme tokens — they flip dark in
   "airsign" dark theme even when nested inside our forced-paper section.
   Pin them to paper tokens so blog stat strips, alert callouts, and bare
   .card grids read correctly in both themes. */
.as-cinema--light .stats,
.as-cinema--light .stat,
.as-prose-card .stats,
.as-prose-card .stat {
  background: var(--as-bg-paper) !important;
  color: var(--as-ink-paper) !important;
  border-color: var(--as-border-paper) !important;
}
.as-cinema--light .stat-title,
.as-prose-card .stat-title {
  color: var(--as-ink-paper-muted) !important;
}
.as-cinema--light .stat-value,
.as-prose-card .stat-value {
  color: var(--as-ink-paper) !important;
}
.as-cinema--light .stat-desc,
.as-prose-card .stat-desc {
  color: var(--as-ink-paper-muted) !important;
}
.as-cinema--light .alert,
.as-prose-card .alert {
  background: oklch(96% 0.04 188);
  color: var(--as-ink-paper);
  border-color: oklch(88% 0.04 188);
}
.as-cinema--light .card:not(.as-card):not(.as-panel):not([class*="as-callout"]):not(.as-article-card),
.as-prose-card .card:not(.as-card):not(.as-panel):not([class*="as-callout"]):not(.as-article-card) {
  background: var(--as-bg-paper);
  color: var(--as-ink-paper);
  border: 1px solid var(--as-border-paper);
}
.as-cinema--light .card:not(.as-card):not(.as-panel):not([class*="as-callout"]):not(.as-article-card) .card-title,
.as-prose-card .card:not(.as-card):not(.as-panel):not([class*="as-callout"]):not(.as-article-card) .card-title {
  color: var(--as-ink-paper);
}
.as-cinema--light .card:not(.as-card):not(.as-panel):not([class*="as-callout"]):not(.as-article-card) p,
.as-cinema--light .card:not(.as-card):not(.as-panel):not([class*="as-callout"]):not(.as-article-card) li,
.as-prose-card .card:not(.as-card):not(.as-panel):not([class*="as-callout"]):not(.as-article-card) p,
.as-prose-card .card:not(.as-card):not(.as-panel):not([class*="as-callout"]):not(.as-article-card) li {
  color: var(--as-ink-paper-muted);
}

/* Section sub-nav — appears after hero scrolls past, sits below main nav.
   Mounted via Alpine x-show (display:none until shown), with slide-in
   transition. x-cloak hides it before Alpine boots. */
[x-cloak] {
  display: none !important;
}

.as-subnav {
  position: sticky;
  top: var(--as-nav-h); /* sits flush below the main nav */
  z-index: 40;
  background: oklch(8% 0.012 250 / 0.86);
  backdrop-filter: saturate(1.4) blur(14px);
  -webkit-backdrop-filter: saturate(1.4) blur(14px);
  border-top: 1px solid oklch(100% 0 0 / 0.05);
  border-bottom: 1px solid oklch(100% 0 0 / 0.06);
  color: var(--as-ink-on-dark);
}

/* Alpine x-transition helper classes — applied during enter/leave. */
.as-subnav-anim-in,
.as-subnav-anim-out {
  transition:
    transform 280ms cubic-bezier(0.22, 0.61, 0.36, 1),
    opacity 220ms ease;
}
.as-subnav-anim-in-state {
  transform: translateY(0);
  opacity: 1;
}
.as-subnav-anim-out-state {
  transform: translateY(-100%);
  opacity: 0;
}
@media (prefers-reduced-motion: reduce) {
  .as-subnav-anim-in,
  .as-subnav-anim-out {
    transition: opacity 0ms;
  }
  .as-subnav-anim-out-state {
    transform: none;
  }
}
.as-subnav__inner {
  max-width: var(--as-maxw-content);
  margin-inline: auto;
  padding: 0.5rem 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  flex-wrap: wrap;
}
.as-subnav__brand {
  font-family: var(--as-font-display);
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--as-ink-on-dark);
  margin-right: auto;
}
.as-subnav__links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: 0.25rem;
  overflow-x: auto;
  scrollbar-width: none;
}
.as-subnav__links::-webkit-scrollbar {
  display: none;
}
.as-subnav__links a {
  position: relative;
  display: inline-block;
  padding: 0.4375rem 0.75rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--as-ink-on-dark-muted);
  text-decoration: none;
  border-radius: var(--as-radius-sm);
  white-space: nowrap;
  transition:
    color 150ms ease,
    background 150ms ease;
}
.as-subnav__links a:hover {
  color: var(--as-ink-on-dark);
  background: oklch(100% 0 0 / 0.06);
}
.as-subnav__links a.is-current {
  color: var(--as-ink-on-dark);
  background: oklch(100% 0 0 / 0.1);
}
.as-subnav__links a.is-current::before {
  content: '';
  position: absolute;
  inset-inline: 0.75rem;
  bottom: -0.5rem;
  height: 2px;
  background: linear-gradient(90deg, transparent, var(--as-accent), transparent);
  border-radius: 2px;
}
.as-subnav__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  padding: 0.4375rem 0.875rem;
  font-size: 0.8125rem;
  font-weight: 600;
  color: white !important;
  background: var(--as-accent);
  border-radius: 999px;
  text-decoration: none;
  transition: background 150ms ease;
}
.as-subnav__cta:hover {
  background: var(--as-accent-hover);
}

/* Story block — Apple's recurring full-bleed-image + headline + one-line + arrow-link.
   Single source of truth: structure + interaction live together so cascade
   order can't accidentally override radius / border between blocks. */
.as-story {
  position: relative;
  isolation: isolate;
  border: 1px solid oklch(100% 0 0 / 0.06);
  border-radius: var(--as-radius-lg);
  overflow: hidden;
  min-height: clamp(380px, 60vh, 620px);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: clamp(1.5rem, 3vw, 2.75rem);
  background: oklch(10% 0.014 250);
  color: var(--as-ink-on-dark);
  cursor: default;
  transition:
    transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1),
    box-shadow 320ms ease,
    border-color 220ms ease;
}
.as-story:hover {
  transform: translateY(-4px);
  border-color: oklch(100% 0 0 / 0.14);
  box-shadow: 0 24px 56px -28px oklch(0% 0 0 / 0.6);
}
.as-story:focus-visible {
  outline: 2px solid var(--as-accent);
  outline-offset: 2px;
}
/* Works whether applied to a <div> wrapper (drift section uses a plain div
   for a CSS-only background) or directly to an <img> (kundberättelser
   section uses <img class="as-story__bg">). object-fit and 100% sizing are
   inert on a div but make the image fill the card on an img. */
.as-story__bg {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.as-story__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    oklch(0% 0 0 / 0.1) 0%,
    oklch(0% 0 0 / 0.45) 60%,
    oklch(0% 0 0 / 0.78) 100%
  );
  z-index: -1;
}
.as-story__eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: oklch(82% 0.13 184);
  margin-bottom: 0.75rem;
}
.as-story__title {
  font-family: var(--as-font-display);
  font-weight: 600;
  font-size: clamp(1.875rem, 4vw, 3rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--as-ink-on-dark);
  margin-bottom: 0.625rem;
  max-width: 28ch;
}
.as-story__line {
  font-size: clamp(1rem, 1.4vw, 1.125rem);
  color: var(--as-ink-on-dark-muted);
  max-width: 36rem;
  margin-bottom: 1.25rem;
}
/* Specificity override — `.as-cinema h2/h3 { color: var(--as-cinema-ink) }`
   wins over `.as-story__title` (single-class selector) because the cinema
   rule has 1 class + 1 type. Restore always-light text for story cards
   inside cinema since they have their own dark image-bg / mood-gradient
   surfaces and need light text regardless of cinema theme. */
.as-cinema .as-story h1,
.as-cinema .as-story h2,
.as-cinema .as-story h3,
.as-cinema .as-story .as-story__title,
.as-cinema .as-story .as-story__line {
  color: var(--as-ink-on-dark);
}
.as-cinema .as-story .as-story__line {
  color: var(--as-ink-on-dark-muted);
}
/* `.as-story--light` is an always-light variant — uses paper tokens so it
   doesn't invert in dark theme. Pair with the white scrim below. */
.as-story--light {
  background: var(--as-bg-paper-alt);
  color: var(--as-ink-paper);
}
.as-story--light .as-story__title {
  color: var(--as-ink-paper);
}
.as-story--light .as-story__line {
  color: var(--as-ink-paper-muted);
}
.as-story--light .as-story__scrim {
  background: linear-gradient(
    180deg,
    oklch(100% 0 0 / 0) 0%,
    oklch(100% 0 0 / 0.45) 60%,
    oklch(100% 0 0 / 0.85) 100%
  );
}

/* Story mood gradients — replaces ad-hoc inline `style="background: ..."` on
   homepage drift/SLA stories. Hue rotates around the brand axis so each card
   feels distinct without escaping the palette. Lightness stays low so the
   on-dark text contrast is preserved.

   Mood variants don't have a bg image, so the flex-end justification (built
   for image-bg cards) leaves dead space at the top. Tighten the min-height
   and center-justify so the text floats sensibly. */
.as-story--mood-blue,
.as-story--mood-cyan,
.as-story--mood-violet,
.as-story--mood-green {
  min-height: clamp(260px, 32vh, 360px);
  justify-content: center;
}
.as-story--mood-blue {
  background: linear-gradient(135deg, oklch(20% 0.04 240), oklch(12% 0.02 240));
}
.as-story--mood-cyan {
  background: linear-gradient(135deg, oklch(22% 0.05 200), oklch(10% 0.02 240));
}
.as-story--mood-violet {
  background: linear-gradient(135deg, oklch(18% 0.06 280), oklch(10% 0.02 240));
}
.as-story--mood-green {
  background: linear-gradient(135deg, oklch(20% 0.05 160), oklch(10% 0.02 240));
}

/* Story grid — masonry-ish 1/2/3-up arrangements */
.as-story-rail {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
}
@media (min-width: 768px) {
  .as-story-rail--2 {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 1024px) {
  .as-story-rail--3 {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (min-width: 1024px) {
  .as-story-rail--asym {
    grid-template-columns: 2fr 1fr;
  }
}

/* Arrow link — tiny CTA used inside stories and cinema sections */
.as-arrow-link {
  display: inline-flex;
  align-items: center;
  gap: 0.375rem;
  font-size: 0.9375rem;
  font-weight: 500;
  color: oklch(82% 0.13 184);
  text-decoration: none;
  transition:
    gap 150ms ease,
    color 150ms ease;
}
.as-arrow-link::after {
  content: '›';
  font-size: 1.125rem;
  line-height: 1;
  transform: translateY(-1px);
  transition: transform 150ms ease;
}
.as-arrow-link:hover {
  gap: 0.5rem;
  color: oklch(88% 0.13 184);
}
.as-arrow-link:hover::after {
  transform: translate(2px, -1px);
}
.as-cinema--light .as-arrow-link,
.as-story--light .as-arrow-link {
  color: var(--as-accent);
}

/* Inline link inside body copy — subtle accent underline so it reads as a
   link without the chevron CTA flavour of `.as-arrow-link`. Matches surrounding
   ink colour so it doesn't fight the line; on hover the accent surfaces. */
.as-inline-link {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: oklch(82% 0.13 184 / 0.5);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition:
    text-decoration-color 150ms ease,
    color 150ms ease;
}
.as-inline-link:hover {
  color: oklch(88% 0.13 184);
  text-decoration-color: oklch(82% 0.13 184);
}
.as-cinema--light .as-inline-link:hover,
.as-story--light .as-inline-link:hover {
  color: var(--as-accent);
  text-decoration-color: var(--as-accent);
}

/* Cinema CTA cluster — primary button on dark + arrow link.
   No `display:` here so Tailwind's `flex flex-col sm:flex-row` utilities
   on the same element control the layout direction. We only contribute
   wrapping + alignment defaults. */
.as-cinema-cta {
  align-items: center;
  flex-wrap: wrap;
}
.as-cinema-cta .as-btn-primary {
  background: white;
  color: #000 !important;
  border-color: white;
}
.as-cinema-cta .as-btn-primary:hover {
  background: oklch(92% 0.005 240);
  border-color: oklch(92% 0.005 240);
}

/* PlaySign app grid — small uniform tiles like an app launcher */
.as-app-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.75rem;
}
@media (min-width: 640px) {
  .as-app-grid {
    grid-template-columns: repeat(4, 1fr);
  }
}
@media (min-width: 1024px) {
  .as-app-grid {
    grid-template-columns: repeat(6, 1fr);
    gap: 1rem;
  }
}
.as-app-tile {
  aspect-ratio: 1 / 1;
  border-radius: var(--as-radius-md);
  background: linear-gradient(135deg, oklch(20% 0.04 240) 0%, oklch(14% 0.03 240) 100%);
  border: 1px solid oklch(100% 0 0 / 0.06);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.375rem;
  color: var(--as-ink-on-dark);
  text-decoration: none;
  transition:
    transform 200ms ease,
    border-color 200ms ease;
}
.as-app-tile:hover {
  transform: translateY(-2px);
  border-color: oklch(100% 0 0 / 0.18);
}
.as-app-tile i {
  font-size: clamp(1.5rem, 2.5vw, 2rem);
  color: oklch(82% 0.13 184);
}
.as-app-tile span {
  font-size: 0.75rem;
  color: var(--as-ink-on-dark-muted);
  text-align: center;
  padding-inline: 0.375rem;
  line-height: 1.2;
}

/* Stats strip — quiet, integrated into narrative */
.as-cinema-stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 2rem 3rem;
  max-width: 56rem;
  margin-inline: auto;
  text-align: center;
}
@media (min-width: 768px) {
  .as-cinema-stats {
    grid-template-columns: repeat(4, 1fr);
  }
}
.as-cinema-stat__value {
  font-family: var(--as-font-display);
  font-size: clamp(2rem, 3.5vw, 2.75rem);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1;
  color: var(--as-cinema-ink);
  margin-bottom: 0.375rem;
}
.as-cinema--light .as-cinema-stat__value {
  color: var(--as-ink-paper);
}
.as-cinema-stat__label {
  font-size: 0.8125rem;
  color: var(--as-cinema-ink-muted);
  letter-spacing: 0.02em;
  /* Reserve 2 lines so a label that wraps (e.g. "Svensk support, vardagar")
       doesn't make its column taller than the others — the whole row stays
       baseline-aligned even on narrow viewports. */
  min-height: 2lh;
}
.as-cinema--light .as-cinema-stat__label {
  color: var(--as-ink-muted);
}

/* Hero device frame — premium product showcase, edge-fade for the "infinite canvas" effect */
.as-hero-stage {
  position: relative;
  margin-inline: auto;
  max-width: 78rem;
  padding-inline: 1rem;
}
/* Works whether applied to a <div> wrapper (legacy markup) or directly to
   an <img> (current markup). Display + width keep the image responsive
   inside its .as-hero-stage container regardless. */
.as-hero-stage__device {
  position: relative;
  display: block;
  width: 100%;
  height: auto;
  border-radius: clamp(12px, 1.4vw, 18px);
  border: 1px solid oklch(100% 0 0 / 0.08);
  background: oklch(10% 0.014 250);
  overflow: hidden;
  box-shadow:
    0 1px 0 oklch(100% 0 0 / 0.06) inset,
    0 60px 120px -40px oklch(0% 0 0 / 0.65),
    0 20px 50px -20px oklch(58% 0.13 184 / 0.2);
}
.as-hero-stage__device img {
  width: 100%;
  height: auto;
  display: block;
}
.as-hero-stage__glow {
  position: absolute;
  inset: -10% -5% -20% -5%;
  background: radial-gradient(
    ellipse 50% 30% at 50% 100%,
    oklch(45% 0.13 184 / 0.45) 0%,
    transparent 70%
  );
  z-index: -1;
  filter: blur(40px);
}

/* Pricing trio (cinema-styled) — 3 plan tiles, one feature row */
.as-pricing-trio {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  max-width: 64rem;
  margin-inline: auto;
}
@media (min-width: 768px) {
  .as-pricing-trio {
    grid-template-columns: repeat(3, 1fr);
  }
}
.as-pricing-tile {
  background: oklch(12% 0.018 250);
  border: 1px solid oklch(100% 0 0 / 0.08);
  border-radius: var(--as-radius-lg);
  padding: 1.75rem;
  color: var(--as-ink-on-dark);
  display: flex;
  flex-direction: column;
  gap: 0.625rem;
}
.as-pricing-tile--featured {
  background: oklch(18% 0.04 184);
  border-color: oklch(50% 0.1 184);
  /* Make room for the ribbon, which sits above the top edge. */
  position: relative;
  margin-top: 0.875rem;
}
/* "Rekommenderat" / "Bäst värde" ribbon — sits above the top edge of the
   featured tile, accent-coloured so it reads as the visual anchor of the row.
   Keep markup terse: <div class="as-pricing-tile__ribbon">Rekommenderat</div>
   inside a `.as-pricing-tile--featured`. */
.as-pricing-tile__ribbon {
  position: absolute;
  top: -0.875rem;
  left: 50%;
  transform: translateX(-50%);
  padding: 0.3125rem 0.875rem;
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: white;
  background: var(--as-accent);
  border-radius: 999px;
  white-space: nowrap;
  box-shadow: 0 4px 12px -4px oklch(58% 0.13 184 / 0.55);
}
.as-pricing-tile__name {
  font-family: var(--as-font-display);
  font-size: 1.125rem;
  font-weight: 600;
}
.as-pricing-tile__price {
  font-family: var(--as-font-display);
  font-size: 2.25rem;
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1;
}
.as-pricing-tile__per {
  font-size: 0.8125rem;
  color: var(--as-ink-on-dark-muted);
  margin-bottom: 0.5rem;
}
.as-pricing-tile ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.5rem;
  font-size: 0.875rem;
}
.as-pricing-tile li {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  color: var(--as-ink-on-dark-muted);
}
.as-pricing-tile li i {
  color: oklch(78% 0.2 130);
  flex-shrink: 0;
  margin-top: 2px;
}
.as-pricing-tile .as-btn-primary {
  margin-top: auto;
  justify-content: center;
}
/* Pricing tiles are dark cards even inside .as-cinema--light. DaisyUI's
   .btn-outline uses --bc (the page text colour) which is near-invisible on
   the tile's dark background. Force on-dark colours so "Starta" / "Kontakta
   sälj" stay readable. */
.as-pricing-tile .btn.btn-outline {
  color: var(--as-ink-on-dark) !important;
  border-color: oklch(100% 0 0 / 0.22);
  background: transparent;
  margin-top: auto;
  justify-content: center;
}
.as-pricing-tile .btn.btn-outline:hover {
  color: #000 !important;
  background: oklch(100% 0 0 / 0.92);
  border-color: oklch(100% 0 0 / 0.92);
}

/* Mini calculator on cinema canvas */
.as-cinema-calc {
  background: oklch(12% 0.018 250);
  border: 1px solid oklch(100% 0 0 / 0.08);
  border-radius: var(--as-radius-xl);
  padding: clamp(1.5rem, 3vw, 2.5rem);
  color: var(--as-ink-on-dark);
  display: grid;
  gap: 1.5rem;
  max-width: 56rem;
  margin-inline: auto;
}
.as-cinema-calc__row {
  display: grid;
  gap: 0.5rem;
}
.as-cinema-calc__label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  font-size: 0.8125rem;
  color: var(--as-ink-on-dark-muted);
  letter-spacing: 0.02em;
}
.as-cinema-calc__label strong {
  color: var(--as-ink-on-dark);
  font-family: var(--as-font-display);
  font-size: 1rem;
  font-weight: 600;
}
.as-cinema-calc input[type='range'] {
  width: 100%;
  accent-color: var(--as-accent);
}
.as-cinema-calc__seg {
  display: inline-flex;
  background: oklch(100% 0 0 / 0.05);
  border: 1px solid oklch(100% 0 0 / 0.1);
  border-radius: 999px;
  padding: 0.25rem;
  flex-wrap: wrap;
}
.as-cinema-calc__seg label {
  padding: 0.4375rem 0.875rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--as-ink-on-dark-muted);
  cursor: pointer;
  border-radius: 999px;
  transition:
    background 150ms ease,
    color 150ms ease;
}
.as-cinema-calc__seg input {
  display: none;
}
.as-cinema-calc__seg input:checked + span {
  background: white;
  color: #000;
}
.as-cinema-calc__seg label span {
  display: inline-block;
  padding: 0.4375rem 0.875rem;
  border-radius: 999px;
  margin: -0.4375rem -0.875rem;
}
.as-cinema-calc__result {
  padding-top: 1.5rem;
  border-top: 1px solid oklch(100% 0 0 / 0.08);
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
}
@media (min-width: 640px) {
  .as-cinema-calc__result {
    grid-template-columns: repeat(2, 1fr);
  }
}
.as-cinema-calc__big {
  font-family: var(--as-font-display);
  font-size: clamp(2.25rem, 4vw, 3rem);
  font-weight: 600;
  letter-spacing: -0.025em;
  line-height: 1;
  color: var(--as-ink-on-dark);
}
.as-cinema-calc__small {
  font-size: 0.8125rem;
  color: var(--as-ink-on-dark-muted);
  margin-top: 0.375rem;
}

/* `.as-cinema--burst` was retired 2026-04-26 — the brand-color radial +
   grid overlay was busier than the rest of the Linear/Vercel ground state
   and only saw 4× usage across 17 templates. The 4 sites that used it now
   use default `.as-cinema` (3 of them) or `.as-cinema--alt --tight` (the
   blog categories strip) for rhythm contrast against their neighbours. */

/* Story card — image-zoom on hover (base hover/lift lives with .as-story above). */
.as-story__bg {
  transition: transform 480ms cubic-bezier(0.22, 0.61, 0.36, 1);
  will-change: transform;
}
.as-story:hover .as-story__bg {
  transform: scale(1.04);
}

/* Trust strip — thin, on-brand row of badges between final CTA and footer. */
.as-trust-strip {
  background: oklch(7% 0.012 250);
  border-top: 1px solid oklch(100% 0 0 / 0.06);
  border-bottom: 1px solid oklch(100% 0 0 / 0.06);
  padding-block: clamp(2rem, 4vw, 3rem);
}
.as-trust-strip__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(1.5rem, 4vw, 4rem);
  flex-wrap: wrap;
  max-width: 56rem;
  margin-inline: auto;
}
.as-trust-strip__inner img {
  height: 64px;
  width: auto;
  opacity: 0.92;
  transition:
    opacity 200ms ease,
    transform 200ms ease;
}
.as-trust-strip__inner img:hover {
  opacity: 1;
  transform: scale(1.04);
}

/* Footer — cinema-aligned, dark, doesn't drop off after the cinematic sections. */
.as-footer {
  background: oklch(6% 0.01 250);
  color: var(--as-ink-on-dark);
  padding-block: clamp(3rem, 6vw, 5rem);
  border-top: 1px solid oklch(100% 0 0 / 0.06);
}
.as-footer__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 2.5rem;
  max-width: var(--as-maxw-content);
  margin-inline: auto;
}
@media (min-width: 768px) {
  .as-footer__grid {
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: 3rem;
  }
}
.as-footer__brand .as-footer__logo {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  color: var(--as-ink-on-dark);
  text-decoration: none;
  font-family: var(--as-font-display);
  font-weight: 600;
  font-size: 1.375rem;
  margin-bottom: 1rem;
}
.as-footer__tag {
  color: var(--as-ink-on-dark-muted);
  font-size: 0.9375rem;
  line-height: 1.6;
  max-width: 28rem;
}
.as-footer__title {
  font-family: var(--as-font-display);
  font-size: 0.8125rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--as-ink-on-dark);
  margin-bottom: 0.875rem;
  opacity: 0.7;
}
.as-footer__col ul {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}
.as-footer__col a {
  color: var(--as-ink-on-dark-muted);
  text-decoration: none;
  font-size: 0.9375rem;
  transition: color 150ms ease;
}
.as-footer__col a:hover {
  color: var(--as-ink-on-dark);
}
.as-footer__base {
  margin-top: clamp(2.5rem, 5vw, 4rem);
  padding-top: 1.5rem;
  border-top: 1px solid oklch(100% 0 0 / 0.06);
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  align-items: flex-start;
  color: var(--as-ink-on-dark-muted);
  font-size: 0.8125rem;
}
@media (min-width: 640px) {
  .as-footer__base {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
  }
}
.as-footer__base p {
  margin: 0;
}
.as-footer__base-meta {
  opacity: 0.7;
}

/* Contextual: cards inside cinema sections — auto-adapt via theme-responsive
   `--as-cinema-card-*` tokens so existing .as-card / .card markup looks
   right in both themes without page rewrites. */
.as-cinema .as-card,
.as-cinema .card.as-card {
  background: var(--as-cinema-card-bg);
  border-color: var(--as-cinema-card-border);
  color: var(--as-cinema-ink);
  backdrop-filter: blur(2px);
}
.as-cinema .as-card:hover,
.as-cinema .card.as-card:hover {
  border-color: var(--as-cinema-card-border-hover);
  background: var(--as-cinema-card-bg-hover);
  transform: translateY(-2px);
}
.as-cinema .as-card .card-title,
.as-cinema .card.as-card .card-title {
  color: var(--as-cinema-ink);
}
.as-cinema .as-card p,
.as-cinema .as-card ul,
.as-cinema .card.as-card p,
.as-cinema .card.as-card ul {
  color: var(--as-cinema-ink-muted);
  opacity: 1;
}
.as-cinema .as-card .opacity-70,
.as-cinema .as-card .opacity-80,
.as-cinema .card.as-card .opacity-70,
.as-cinema .card.as-card .opacity-80 {
  color: var(--as-ink-on-dark-muted);
  opacity: 1;
}

/* Fallback for plain DaisyUI `.card` inside cinema (no `.as-card` partner).
   Some blog posts use bare `<div class="card">` without the as-card class,
   which means they don't pick up the cinema-card tokens above and end up
   with DaisyUI's default base-100 surface that flips the wrong way under
   the cinema's inherited text color (invisible text in light theme).
   This rule applies the same theme-responsive cinema-card treatment so
   plain .card markup looks right in both themes without HTML rewrites.
   Excludes .as-card / .as-panel / .as-callout because those have their
   own dedicated cinema overrides. */
.as-cinema .card:not(.as-card):not(.as-panel):not([class*="as-callout"]) {
  background: var(--as-cinema-card-bg);
  border: 1px solid var(--as-cinema-card-border);
  color: var(--as-cinema-ink);
  backdrop-filter: blur(2px);
}
.as-cinema .card:not(.as-card):not(.as-panel):not([class*="as-callout"]):hover {
  border-color: var(--as-cinema-card-border-hover);
  background: var(--as-cinema-card-bg-hover);
}
.as-cinema .card:not(.as-card):not(.as-panel):not([class*="as-callout"]) .card-title,
.as-cinema .card:not(.as-card):not(.as-panel):not([class*="as-callout"]) h2,
.as-cinema .card:not(.as-card):not(.as-panel):not([class*="as-callout"]) h3,
.as-cinema .card:not(.as-card):not(.as-panel):not([class*="as-callout"]) h4 {
  color: var(--as-cinema-ink);
}
.as-cinema .card:not(.as-card):not(.as-panel):not([class*="as-callout"]) p,
.as-cinema .card:not(.as-card):not(.as-panel):not([class*="as-callout"]) ul,
.as-cinema .card:not(.as-card):not(.as-panel):not([class*="as-callout"]) li {
  color: var(--as-cinema-ink-muted);
  opacity: 1;
}

.as-cinema .as-icon-chip {
  background: oklch(100% 0 0 / 0.08);
  color: var(--as-ink-on-dark);
  border-color: oklch(100% 0 0 / 0.1);
}
.as-cinema .as-icon-chip--hero {
  background: oklch(100% 0 0 / 0.1);
  color: var(--as-ink-on-dark);
}
.as-cinema .as-category-header__title {
  color: var(--as-cinema-ink);
}
.as-cinema .as-category-header__body {
  color: var(--as-cinema-ink-muted);
}

/* .as-panel inside cinema — same shape as the .as-card override above.
   Without this, the panel keeps its theme-responsive `--as-bg-alt`
   background which flips to near-white in light theme, while the cinema
   cascade still inherits white text — invisible labels on the demo form,
   testimonial card, and pricing INKLUDERAT panel. Force a dark surface so
   the inherited light text stays legible regardless of the user's theme.
   Excludes `.as-cinema--light` because that section is itself paper-light
   and runs a separate paper-token cascade. */
.as-cinema:not(.as-cinema--light) .as-panel,
.as-cinema:not(.as-cinema--light) .card.as-panel {
  background: oklch(12% 0.02 250 / 0.55);
  border-color: oklch(100% 0 0 / 0.08);
  color: var(--as-ink-on-dark);
  backdrop-filter: blur(2px);
}
.as-cinema:not(.as-cinema--light) .as-panel h2,
.as-cinema:not(.as-cinema--light) .as-panel h3,
.as-cinema:not(.as-cinema--light) .as-panel .card-title {
  color: var(--as-ink-on-dark);
}
.as-cinema:not(.as-cinema--light) .as-panel p,
.as-cinema:not(.as-cinema--light) .as-panel ul {
  color: var(--as-ink-on-dark-muted);
  opacity: 1;
}
.as-cinema:not(.as-cinema--light) .as-panel .opacity-70,
.as-cinema:not(.as-cinema--light) .as-panel .opacity-80 {
  color: var(--as-ink-on-dark-muted);
  opacity: 1;
}
/* Form labels inside a cinema panel — DaisyUI's `.label-text` renders the
   `<span class="label-text">` chips above each input. Without an explicit
   on-dark colour they fall through to the inherited theme `--bc` which
   reads as the body text token (near-white in light theme on the cinema
   canvas — but the panel was unintentionally light too, hiding the label).
   Now the panel is always dark, so labels need on-dark colour. */
.as-cinema:not(.as-cinema--light) .as-panel label,
.as-cinema:not(.as-cinema--light) .as-panel .label,
.as-cinema:not(.as-cinema--light) .as-panel .label-text,
.as-cinema:not(.as-cinema--light) .as-panel .form-control {
  color: var(--as-ink-on-dark);
}

/* Pricing comparison-table section bands (`<tr class="bg-base-200">` used
   as a Grundfunktioner / Avancerade funktioner row separator). DaisyUI's
   base-200 token is near-white in airsign-light, which made the inherited
   on-dark text invisible against the band. Force a dark translucent band
   regardless of theme so the inherited light text stays legible. */
.as-cinema:not(.as-cinema--light) table.table tr.bg-base-200,
.as-cinema:not(.as-cinema--light) table.table tr.bg-base-200 td {
  background: oklch(100% 0 0 / 0.06) !important;
  color: var(--as-ink-on-dark);
}

/* Tables on cinema canvas */
.as-cinema table.table {
  color: var(--as-ink-on-dark);
}
.as-cinema table.table th,
.as-cinema table.table td {
  border-color: oklch(100% 0 0 / 0.08);
}
.as-cinema table.table thead th {
  background: oklch(100% 0 0 / 0.04);
  color: var(--as-ink-on-dark);
}

/* Forms on cinema canvas — inputs, selects, labels */
.as-cinema label,
.as-cinema .label,
.as-cinema .label-text,
.as-cinema .form-control {
  color: var(--as-ink-on-dark);
}
.as-cinema .input,
.as-cinema .textarea,
.as-cinema .select {
  background: oklch(100% 0 0 / 0.04);
  border-color: oklch(100% 0 0 / 0.12);
  color: var(--as-ink-on-dark);
}
.as-cinema .input::placeholder,
.as-cinema .textarea::placeholder {
  color: oklch(70% 0.015 240);
}
.as-cinema .input:focus,
.as-cinema .textarea:focus,
.as-cinema .select:focus {
  border-color: var(--as-accent);
  outline: 2px solid oklch(60% 0.13 184 / 0.4);
  outline-offset: -1px;
}

/* --------------------------------------------------------------------------
   .as-prose — typography for blog-article bodies (used inside as-cinema--light).
   Targets the inner `.prose` markup that already exists in all blog posts.
   Optimized for long-form reading: max 65ch, generous line-height, restrained
   color palette. Apple-News / Medium aesthetic.
   -------------------------------------------------------------------------- */
/* `.as-prose-card` is always a light reading panel — uses the always-light
   `--as-bg-paper` so it doesn't invert when the user is on dark theme. */
.as-prose-card {
  background: var(--as-bg-paper);
  border: 1px solid var(--as-border-paper);
  border-radius: var(--as-radius-lg);
  padding: clamp(1.75rem, 4vw, 3rem);
  max-width: 48rem;
  margin-inline: auto;
  box-shadow: 0 24px 80px -40px oklch(0% 0 0 / 0.25);
}
.as-cinema .as-prose-card .prose,
.as-cinema--light .prose,
.as-prose {
  color: var(--as-ink-paper);
  font-size: 1.0625rem;
  line-height: 1.75;
  max-width: 65ch;
}
.as-cinema--light .prose .lead,
.as-prose .lead {
  font-size: 1.25rem;
  line-height: 1.6;
  color: var(--as-ink-paper);
  font-weight: 500;
  margin-bottom: 2rem;
}
.as-cinema--light .prose h2,
.as-prose h2 {
  font-family: var(--as-font-display);
  font-size: clamp(1.5rem, 2.5vw, 2rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin-top: 3rem;
  margin-bottom: 1rem;
  color: var(--as-ink-paper);
}
.as-cinema--light .prose h3,
.as-prose h3 {
  font-family: var(--as-font-display);
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.3;
  margin-top: 2rem;
  margin-bottom: 0.75rem;
  color: var(--as-ink-paper);
}
.as-cinema--light .prose p,
.as-prose p {
  margin-bottom: 1.25rem;
  color: var(--as-ink-paper);
}
.as-cinema--light .prose ul,
.as-cinema--light .prose ol,
.as-prose ul,
.as-prose ol {
  margin: 1rem 0 1.5rem 1.25rem;
}
.as-cinema--light .prose li,
.as-prose li {
  margin-bottom: 0.5rem;
  color: var(--as-ink-paper);
}
.as-cinema--light .prose ul,
.as-prose ul {
  list-style: disc;
}
.as-cinema--light .prose ol,
.as-prose ol {
  list-style: decimal;
}
.as-cinema--light .prose blockquote,
.as-prose blockquote {
  border-left: 3px solid var(--as-accent);
  padding: 0.5rem 1.25rem;
  margin: 2rem 0;
  font-style: italic;
  color: var(--as-ink-paper-muted);
  background: var(--as-bg-paper-alt);
  border-radius: 0 var(--as-radius-md) var(--as-radius-md) 0;
}
.as-cinema--light .prose a,
.as-prose a {
  color: var(--as-accent);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  text-decoration-thickness: 1px;
}
.as-cinema--light .prose a:hover,
.as-prose a:hover {
  color: var(--as-accent-hover);
}
.as-cinema--light .prose strong,
.as-prose strong {
  color: var(--as-ink-paper);
  font-weight: 600;
}
.as-cinema--light .prose code,
.as-prose code {
  background: oklch(96% 0.006 192);
  border: 1px solid var(--as-border-paper);
  padding: 0.125rem 0.375rem;
  border-radius: var(--as-radius-sm);
  font-size: 0.9em;
  color: var(--as-ink-paper);
}
.as-cinema--light .prose img,
.as-prose img {
  border-radius: var(--as-radius-md);
  margin: 1.5rem 0;
}
.as-cinema--light .prose hr,
.as-prose hr {
  border: 0;
  height: 1px;
  background: var(--as-border-paper);
  margin: 2.5rem 0;
}

/* Inline CTA inside blog prose-card — compact, brand-tinted, eye-catching.
   Overrides .as-cta's section-sized padding when nested inside .prose. */
.as-prose-card .as-cta,
.prose .as-cta {
  padding-block: 0;
  background: linear-gradient(135deg, oklch(20% 0.05 240), oklch(12% 0.02 240));
  color: var(--as-ink-on-dark);
  border-radius: var(--as-radius-lg);
}
.as-prose-card .as-cta::before,
.prose .as-cta::before {
  border-radius: var(--as-radius-lg);
}
.as-prose-card .as-cta .card-body,
.prose .as-cta .card-body {
  padding: clamp(1.5rem, 4vw, 2.5rem);
}
.as-prose-card .as-cta h3,
.prose .as-cta h3 {
  color: var(--as-ink-on-dark);
  font-family: var(--as-font-display);
  margin-top: 0;
}
.as-prose-card .as-cta p,
.prose .as-cta p {
  color: var(--as-ink-on-dark-muted);
}
.as-prose-card .as-cta a,
.prose .as-cta a {
  color: var(--as-ink-on-dark);
}

/* Article hero — used at top of blog posts. Sits on dark canvas with
   breadcrumbs, eyebrow pill, headline. Optional __bg element promotes the
   article's hero image to a full-bleed background under a dark scrim — same
   treatment as `.as-story` cards but at section scale. The doubled selector
   (`.as-cinema.as-article-hero`) wins padding-block specificity over `.as-cinema`. */
.as-cinema.as-article-hero {
  padding-block: clamp(4rem, 7vw, 7rem);
  /* Slightly more vertical room when there's a hero bg image — gives the scrim
       enough surface to grade properly. */
}
.as-article-hero__bg {
  position: absolute;
  inset: 0;
  z-index: -2;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Subject visibility first. The scrim handles title contrast on its own
     via a bottom-weighted gradient, so the image itself only needs a hair
     of dim to integrate with the dark cinema chrome. */
  filter: brightness(0.95);
}
.as-article-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  /* Bottom-weighted scrim: top stays bright so the photograph shows through,
     mid carries a soft transition, bottom darkens hard enough for white title
     + muted meta to clear WCAG AA. Avoids the previous "wash everything"
     gradient that was hiding the actual hero subject. */
  background: linear-gradient(
    180deg,
    oklch(8% 0.012 250 / 0.15) 0%,
    oklch(8% 0.012 250 / 0.35) 35%,
    oklch(8% 0.012 250 / 0.65) 70%,
    oklch(8% 0.012 250 / 0.85) 100%
  );
  pointer-events: none;
}
.as-article-hero__breadcrumbs {
  color: oklch(78% 0.02 200);
  font-size: 0.8125rem;
  margin-bottom: 1.5rem;
}
.as-article-hero__breadcrumbs a {
  color: var(--as-ink-on-dark-muted);
  text-decoration: none;
}
.as-article-hero__breadcrumbs a:hover {
  color: var(--as-ink-on-dark);
}
/* Specificity bump: `.as-cinema h1, h2, h3 { color: var(--as-cinema-ink); }`
   has specificity (0,1,1) and was winning over a single-class rule on the
   title, painting it dark-on-dark in light theme. Compound the article-hero
   class with .as-cinema to land at (0,2,0) and reclaim the color. */
.as-cinema .as-article-hero__title {
  font-family: var(--as-font-display);
  font-size: clamp(2.25rem, 5vw, 3.75rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--as-ink-on-dark);
  margin-bottom: 1.5rem;
  max-width: 22ch;
}
.as-article-hero__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  color: var(--as-ink-on-dark-muted);
  font-size: 0.875rem;
}

/* Button-driven segmented control (Alpine :class="{ 'is-active': ... }") —
   sits next to the existing radio-input pattern for backwards compatibility. */
.as-cinema-calc__seg button {
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  padding: 0.4375rem 0.875rem;
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--as-ink-on-dark-muted);
  cursor: pointer;
  border-radius: 999px;
  transition:
    background 150ms ease,
    color 150ms ease;
  line-height: 1;
}
.as-cinema-calc__seg button:hover {
  color: var(--as-ink-on-dark);
  background: oklch(100% 0 0 / 0.05);
}
.as-cinema-calc__seg button.is-active {
  background: white;
  color: #000;
}
.as-cinema-calc__seg button:focus-visible {
  outline: 2px solid var(--as-accent);
  outline-offset: 2px;
}

/* App grid — overflow tile pointing to the rest of the catalog. */
.as-app-tile--more {
  background: linear-gradient(135deg, oklch(20% 0.06 240), oklch(14% 0.04 240));
  border-color: oklch(100% 0 0 / 0.12);
  color: var(--as-ink-on-dark);
}
.as-app-tile--more i,
.as-app-tile--more span {
  color: var(--as-ink-on-dark);
  opacity: 0.95;
}

/* --------------------------------------------------------------------------
   Defensive flatteners — soak up DaisyUI gradient + heavy-shadow patterns
   that occasionally creep back in. Kept as belt-and-suspenders even now that
   most authored markup has been migrated to `.as-card` / `.as-panel`.
   -------------------------------------------------------------------------- */
.card.bg-gradient-to-br {
  background: var(--as-bg) !important;
  background-image: none !important;
  border: 1px solid var(--as-border) !important;
  box-shadow: none !important;
}
.card.shadow-2xl,
.card.shadow-xl {
  box-shadow: none !important;
  border: 1px solid var(--as-border) !important;
}

/* Tables on cinema canvas — DaisyUI defaults add bg-base-100 + shadow-xl on
   tables which produces an out-of-system white slab on the dark canvas.
   Re-skin to match the cinema palette. Light cinema uses the page tokens. */
.as-cinema table.table.shadow-xl,
.as-cinema table.table.shadow-2xl {
  box-shadow: none !important;
  background: oklch(12% 0.02 250 / 0.55) !important;
  border: 1px solid oklch(100% 0 0 / 0.08);
  border-radius: var(--as-radius-md);
  overflow: hidden;
}
.as-cinema--light table.table.shadow-xl,
.as-cinema--light table.table.shadow-2xl {
  background: var(--as-bg) !important;
}

/* Prose headings — blog articles authored before the design system was
   formalised use raw `text-3xl font-bold mt-12 mb-4` on h2 and `text-2xl`
   on h3 inside .prose. Marketing.css already provides on-token sizes for
   .as-prose h2/h3, but Tailwind utilities win on specificity. Reassert the
   tokens with higher specificity so all 10+ articles read consistently. */
.as-prose-card .prose h2,
.as-cinema--light .prose h2 {
  font-size: clamp(1.5rem, 2.5vw, 2rem) !important;
  line-height: 1.15 !important;
  font-weight: 600 !important;
  margin-top: 3rem !important;
  margin-bottom: 1rem !important;
  letter-spacing: -0.02em;
  font-family: var(--as-font-display);
  color: var(--as-ink-paper);
}
.as-prose-card .prose h3,
.as-cinema--light .prose h3 {
  font-size: 1.25rem !important;
  line-height: 1.3 !important;
  font-weight: 600 !important;
  margin-top: 2rem !important;
  margin-bottom: 0.75rem !important;
  font-family: var(--as-font-display);
  color: var(--as-ink-paper);
}

/* Strip redundant Tailwind list utilities that conflict with prose styling.
   Articles author `<ul class="list-disc list-inside ml-4">` which collides
   with the prose's outdented list-style. Reassert the prose default. */
.as-prose-card .prose ul.list-disc,
.as-cinema--light .prose ul.list-disc {
  list-style: disc;
  list-style-position: outside;
  margin-left: 1.25rem !important;
  padding-left: 0;
}
.as-prose-card .prose ul.list-disc li,
.as-cinema--light .prose ul.list-disc li {
  margin-bottom: 0.5rem;
}

/* --------------------------------------------------------------------------
   Accessibility
   -------------------------------------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--as-accent);
  outline-offset: 2px;
  border-radius: var(--as-radius-sm);
}

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

/* --------------------------------------------------------------------------
   Print
   -------------------------------------------------------------------------- */
@media print {
  .as-hero::before,
  .as-cta::before,
  .as-hero-media__halo {
    display: none;
  }
  body.as-page > nav.navbar,
  body.as-page > footer.footer {
    display: none;
  }
}
