@charset "utf-8";
/* ============================================================================
   ARXEON DESIGN SYSTEM — "PRISM"
   01 · TOKENS
   ----------------------------------------------------------------------------
   Thesis
     The Arxeon mark is light split into a spectrum. So the interface is an
     UNLIT INSTRUMENT: its housing is deliberately colourless, and the only
     colour anywhere is light passing through it.

   Three laws, derived from the mark itself
     1. THE GROUND IS COLOURLESS.  --ink-050 is oklch(0.145 0 0): chroma is
        exactly zero. This is not navy, not slate, not plum. It is ink.
     2. ELEVATION IS SPECTRAL.  Every surface that rises toward the viewer
        gains a measured trace of chroma and rotates along the brand hue arc
        (violet 300deg down low -> cyan 214deg up high). Max chroma in the
        whole ramp is 0.0098 — far below the naming threshold, so it never
        reads as "a colour", it reads as *alive*.
     3. THIRTY DEGREES.  All 11 blades of the mark sit at exactly 30.0 deg
        from vertical (measured, not estimated). Every diagonal, shear, beam
        and edge-gradient in this system uses that axis and no other.

   Measured constants from Images/Arxeon-logo-darkBG.svg
     · blade angle ........ 30.0deg from vertical (all 11 blades)
     · art bounding box ... 110.3 116.8 1377.4 1220.9  (aspect 1.1282)
     · tip step ........... 116.45 units, constant
     · blade decay ........ 1.203, 1.208, 1.222 at the large end -> the
                            typographic scale ratio is 1.200
     · spectrum ........... 9 stops, #05C4FC -> #8E0EC6

   Authored in OKLCH for perceptual evenness, shipped as hex so nothing
   depends on oklch() support. The oklch() source of every value is in the
   comment beside it.
   ========================================================================= */

/* ── 0 · REGISTERED PROPERTIES ───────────────────────────────────────────
   A custom property is an unparsed token by default, so it cannot be
   transitioned — which is why gradient-driven effects normally have to snap.
   Registering --ax-bloom as a <number> and --ax-arc as a <percentage> makes
   them interpolate, and that is the whole of the button hover: the light in
   the base RISES and the two lit arcs REACH AROUND until the ring closes.
   Without registration both would snap. These are the only two registered
   properties in the system.
   Unsupported engines fall back to initial-value and the effect is simply
   static; nothing breaks.                                                */

@property --ax-bloom {
  syntax: "<number>";
  initial-value: 0.26;
  inherits: false;
}
@property --ax-arc {
  syntax: "<percentage>";
  initial-value: 34%;
  inherits: false;
}

:root {

  /* ── 1 · SPECTRUM ────────────────────────────────────────────────────────
     The nine stops lifted verbatim from the logo's linearGradient. Never
     re-order them, never invert the ramp, never add a stop.               */

  --ax-spec-0: #05C4FC;   /* oklch(.766 .148 228)  cyan      — the tip      */
  --ax-spec-1: #07C1FB;   /* oklch(.758 .149 229)                          */
  --ax-spec-2: #0FB7F8;   /* oklch(.734 .151 234)                          */
  --ax-spec-3: #1CA6F3;   /* oklch(.694 .156 241)                          */
  --ax-spec-4: #2E8EEC;   /* oklch(.639 .166 252)  azure    — the midpoint */
  --ax-spec-5: #456FE3;   /* oklch(.575 .183 266)                          */
  --ax-spec-6: #6149D8;   /* oklch(.517 .208 284)  indigo                  */
  --ax-spec-7: #821ECB;   /* oklch(.495 .238 304)                          */
  --ax-spec-8: #8E0EC6;   /* oklch(.500 .245 311)  violet   — the base     */

  /* Named handles. Use these in components, not the numbered stops. */
  --ax-cyan:        var(--ax-spec-0);
  --ax-azure:       var(--ax-spec-4);
  --ax-indigo:      var(--ax-spec-6);
  --ax-violet:      var(--ax-spec-8);

  /* The darkest point on the brand ramp that still clears 4.5:1 beneath
     --ax-text-on-spec (it measures 5.00:1). It sits 60% of the way from
     spec-4 to spec-5, so it is genuinely on the logo's ramp — it is simply
     where a filled control has to stop travelling. Ending a primary fill on
     spec-5 itself measures 4.42:1 and fails. */
  --ax-spec-floor:  #3C7CE8;

  /* ── THE DISCIPLINE RAMP ──────────────────────────────────────────────
     Arxeon is one company split into four disciplines, and the mark is one
     light split into a spectrum — so the disciplines ARE the spectrum, in
     order of how near they sit to the core of the business. That is the site
     map (see section 18 of the components file).

     But the logo's own stops are a FILL ramp, drawn for a large mark on
     black. As TEXT the dark end fails badly: spec-6 measures 3.19:1 and
     spec-8 measures 2.80:1 against a panel — unreadable as a label. These
     four keep each stop's exact hue and raise only its lightness, pulling
     chroma back no further than sRGB forces. Every one clears 4.6:1 on all
     five surfaces this system paints.

       01 health technology  spec-0  unchanged          9.52:1
       02 AI                 spec-3  unchanged          7.20:1
       03 engineering        hue 284  L .517 -> .650    4.67:1
       04 construction       hue 311  L .500 -> .660    4.67:1                */

  --ax-div-1: #05C4FC;   /* health technology */
  --ax-div-2: #1CA6F3;   /* AI                */
  --ax-div-3: #8576FF;   /* engineering       */
  --ax-div-4: #C059F9;   /* construction      */

  --ax-cyan-bright:   #61E3FF;  /* oklch(.86 .13 225) — hover / emphasis   */
  --ax-cyan-deep:     #0070AB;  /* oklch(.52 .13 240) — pressed / rails    */
  --ax-violet-bright: #D574FD;  /* oklch(.72 .21 315)                      */
  --ax-violet-deep:   #5F0E87;  /* oklch(.38 .18 310)                      */

  /* Channel triplets — for rgba() composition without colour-mix(). */
  --ax-cyan-rgb:    5 196 252;
  --ax-cyan-bright-rgb:  97 227 255;
  --ax-violet-bright-rgb: 213 116 253;
  --ax-azure-rgb:   46 142 236;
  --ax-indigo-rgb:  97  73 216;
  --ax-violet-rgb: 142  14 198;
  --ax-white-rgb:  255 255 255;
  --ax-black-rgb:    0   0   0;


  /* ── 2 · INK — the achromatic housing ────────────────────────────────────
     Chroma column: 0 · 0 · 0 · .004 · .005 · .006 · .008 · .009 · .009 ·
     .010 · .009 · .007 · .005 · .003. Hue rotates 300 -> 214 as it rises. */

  --ax-ink-000: #000000;  /* oklch(.000 0     300) void — scrims only      */
  --ax-ink-025: #040404;  /* oklch(.108 0     300) the page beneath the page */
  --ax-ink-050: #0A0A0A;  /* oklch(.145 0     300) ▸ CANVAS. chroma = zero */
  --ax-ink-100: #131214;  /* oklch(.184 .0040 300) sunken                  */
  --ax-ink-150: #19191B;  /* oklch(.214 .0052 294) surface                 */
  --ax-ink-200: #202023;  /* oklch(.245 .0062 288) raised                  */
  --ax-ink-300: #2C2D31;  /* oklch(.296 .0076 276) overlay / hairline hi   */
  --ax-ink-400: #393B40;  /* oklch(.352 .0086 262) border strong           */
  --ax-ink-500: #4C5055;  /* oklch(.430 .0094 248) disabled ink            */
  --ax-ink-600: #6A7074;  /* oklch(.540 .0098 238) ▸ NOT A TEXT COLOUR     */
  --ax-ink-650: #848A8E;  /* oklch(.630 .0098 236) lowest legal text step  */
  --ax-ink-700: #8E9598;  /* oklch(.665 .0090 230) secondary text          */
  --ax-ink-800: #B9BFC1;  /* oklch(.800 .0070 224) body text               */
  --ax-ink-900: #DDE1E3;  /* oklch(.908 .0048 218) strong text             */
  --ax-ink-950: #F3F6F6;  /* oklch(.970 .0028 214) ▸ headline. never #fff  */


  /* ── 3 · SURFACE ROLES ──────────────────────────────────────────────────
     Components reference roles; roles reference the ramp. Retheming a whole
     section means overriding six variables, never touching a component.   */

  --ax-bg:            var(--ax-ink-050);
  --ax-bg-sunken:     var(--ax-ink-025);
  --ax-surface:       var(--ax-ink-100);
  --ax-surface-2:     var(--ax-ink-150);
  --ax-surface-3:     var(--ax-ink-200);
  --ax-surface-hover: var(--ax-ink-200);
  --ax-overlay:       var(--ax-ink-150);

  --ax-text:          var(--ax-ink-900);
  --ax-text-strong:   var(--ax-ink-950);
  --ax-text-body:     var(--ax-ink-800);
  --ax-text-muted:    var(--ax-ink-700);
  --ax-text-subtle:   var(--ax-ink-650);
  --ax-text-disabled: var(--ax-ink-500);
  --ax-text-on-spec:  #06080C;    /* ink that sits ON a spectrum fill       */

  /* ── CONTRAST CONTRACT ────────────────────────────────────────────────
     Measured against the four surfaces this system actually paints —
     #0A0A0A, #131214, #19191B, #202023 — so a token is safe anywhere,
     not just on the canvas.

       text-strong  #F3F6F6   18.22 : 1  …  14.95 : 1
       text-body    #B9BFC1   10.64      …   8.73
       text-muted   #8E9598    6.51      …   5.34
       text-subtle  #848A8E    5.66      …   4.65   ← the floor
       cyan         #05C4FC    9.72      …   7.98
       danger       #FC436F    5.82      …   4.78

     ink-600 and everything below it are BORDER AND FILL values. They do
     not pass 4.5:1 as text on any surface here — the previous build used
     ink-600 for captions and help text at 3.94:1, which is why ink-650
     exists. If a new text role is needed, add a step; never reach down. */

  --ax-line:          rgb(var(--ax-white-rgb) / .07);   /* default hairline */
  --ax-line-soft:     rgb(var(--ax-white-rgb) / .045);
  --ax-line-strong:   rgb(var(--ax-white-rgb) / .13);
  --ax-line-spec:     rgb(var(--ax-cyan-rgb) / .32);


  /* ── 4 · STATUS — one lightness family, so they read as siblings ───────── */

  --ax-success:      #00D89F;  /* oklch(.78 .165 166) */
  --ax-success-dim:  #007655;  /* oklch(.50 .105 166) */
  --ax-warning:      #F5B430;  /* oklch(.81 .155  80) */
  --ax-warning-dim:  #876114;  /* oklch(.52 .100  80) */
  --ax-danger:       #FC436F;  /* oklch(.665 .22  12) — text/border only */
  --ax-danger-fill:  #C70046;  /* oklch(.520 .22  12) — filled surface;
                                  white on it is 5.97:1, the bright rose
                                  above manages only 3.40:1               */
  --ax-danger-fill-hi: #D50B51;/* oklch(.560 .22  12) — its hover          */
  --ax-danger-dim:   #8F263D;  /* oklch(.44 .140  12) */
  --ax-info:         #03C3F7;  /* oklch(.76 .145 226) */

  --ax-success-rgb:   0 216 159;
  --ax-warning-rgb: 245 180  48;
  --ax-danger-rgb:  252  67 111;


  /* ── 5 · THE AXIS — 30 degrees, from the mark ───────────────────────────
     --ax-axis         shear/rotate value for blades and beams
     --ax-axis-grad    gradient direction along a blade (cyan up-right ->
                       violet down-left) = 180 + 30 = 210deg
     --ax-axis-fill    the logo's own fill direction: straight down         */

  --ax-axis:       -30deg;
  --ax-axis-grad:   210deg;
  --ax-axis-fill:   180deg;

  /* The spectrum, as reusable paint. */
  --ax-grad-fill:  linear-gradient(var(--ax-axis-fill),
                     var(--ax-spec-0) 0%,  var(--ax-spec-1) 18.67%,
                     var(--ax-spec-2) 33.67%, var(--ax-spec-3) 47.40%,
                     var(--ax-spec-4) 60.37%, var(--ax-spec-5) 72.81%,
                     var(--ax-spec-6) 84.85%, var(--ax-spec-7) 96.35%,
                     var(--ax-spec-8) 100%);
  --ax-grad-axis:  linear-gradient(var(--ax-axis-grad),
                     var(--ax-spec-0), var(--ax-spec-4) 46%,
                     var(--ax-spec-6) 74%, var(--ax-spec-8));

  /* THE FILL RULE
     A spectral fill that CARRIES something — text, an icon, a checkmark —
     stops at --ax-spec-floor, because --ax-text-on-spec measures only
     2.89:1 against the violet end and 5.00:1 against the floor. A spectral
     fill that carries NOTHING (a rail, a hairline, a progress bar, a glow)
     may run the whole ramp. Use -carry wherever content sits on top. */
  --ax-grad-carry: linear-gradient(var(--ax-axis-grad),
                     var(--ax-spec-0), var(--ax-spec-2) 34%,
                     var(--ax-spec-4) 72%, var(--ax-spec-floor));
  --ax-grad-carry-sweep: linear-gradient(90deg,
                     var(--ax-spec-0), var(--ax-spec-2) 30%,
                     var(--ax-spec-4) 70%, var(--ax-spec-floor));
  --ax-grad-sweep: linear-gradient(90deg,
                     var(--ax-spec-0), var(--ax-spec-4) 38%,
                     var(--ax-spec-6) 70%, var(--ax-spec-8));
  --ax-grad-hair:  linear-gradient(90deg, transparent,
                     rgb(var(--ax-cyan-rgb)/.55) 20%,
                     rgb(var(--ax-indigo-rgb)/.55) 52%,
                     rgb(var(--ax-violet-rgb)/.50) 78%, transparent);

  /* THE REFRACTION EDGE — the system's signature. A border is never a flat
     colour; it is light grazing an edge: bright where it catches, gone
     where it doesn't. Applied via padding-box/border-box compositing.    */
  --ax-edge:       linear-gradient(var(--ax-axis-grad),
                     rgb(var(--ax-cyan-rgb)/.30) 0%,
                     rgb(var(--ax-white-rgb)/.055) 34%,
                     rgb(var(--ax-white-rgb)/.03) 58%,
                     rgb(var(--ax-violet-rgb)/.24) 100%);
  --ax-edge-hi:    linear-gradient(var(--ax-axis-grad),
                     rgb(var(--ax-cyan-rgb)/.72) 0%,
                     rgb(var(--ax-indigo-rgb)/.32) 42%,
                     rgb(var(--ax-violet-rgb)/.62) 100%);
  --ax-edge-quiet: linear-gradient(var(--ax-axis-grad),
                     rgb(var(--ax-white-rgb)/.10),
                     rgb(var(--ax-white-rgb)/.03) 55%,
                     rgb(var(--ax-white-rgb)/.07));


  /* ── 6 · TYPE ───────────────────────────────────────────────────────────
     Manrope carries the voice; IBM Plex Mono is the instrument read-out
     used for eyebrows, metrics and code. Scale ratio 1.200, taken from the
     mark's blade decay (1.203 / 1.208 / 1.222 at the large end).         */

  --ax-font-sans: "Manrope", "Manrope Fallback", ui-sans-serif, -apple-system,
                  "Segoe UI Variable Text", "Segoe UI", Roboto, "Helvetica Neue",
                  Arial, sans-serif;
  --ax-font-mono: "IBM Plex Mono", ui-monospace, "Cascadia Code", "SF Mono",
                  Menlo, Consolas, "Liberation Mono", monospace;

  --ax-fs-3xs: 0.6875rem;  /* 11.00 */
  --ax-fs-2xs: 0.75rem;    /* 12.00 */
  --ax-fs-xs:  0.8333rem;  /* 13.33 */
  --ax-fs-sm:  0.875rem;   /* 14.00 */
  --ax-fs-md:  1rem;       /* 16.00  ← base */
  --ax-fs-lg:  1.2rem;     /* 19.20 */
  --ax-fs-xl:  1.44rem;    /* 23.04 */
  --ax-fs-2xl: 1.728rem;   /* 27.65 */
  --ax-fs-3xl: 2.0736rem;  /* 33.18 */
  --ax-fs-4xl: 2.4883rem;  /* 39.81 */
  --ax-fs-5xl: 2.986rem;   /* 47.78 */
  --ax-fs-6xl: 3.5832rem;  /* 57.33 */
  --ax-fs-7xl: 4.2998rem;  /* 68.80 */
  --ax-fs-8xl: 5.1598rem;  /* 82.56 */

  /* Fluid display sizes. Each clamp lands exactly on a ladder step at both
     ends, so the scale stays true at 360px and at 1440px. */
  --ax-fs-d1: clamp(2.4883rem, 1.30rem + 5.28vw, 5.1598rem);
  --ax-fs-d2: clamp(2.0736rem, 1.24rem + 3.71vw, 3.5832rem);
  --ax-fs-d3: clamp(1.728rem,  1.19rem + 2.39vw, 2.6rem);
  --ax-fs-d4: clamp(1.44rem,   1.13rem + 1.38vw, 2.0736rem);

  /* Optical tracking — letter-spacing must tighten as size grows, or large
     type looks loose and small type looks cramped. Never hard-code these. */
  --ax-tr-micro:    0.06em;   /* 11px uppercase eyebrows */
  --ax-tr-tiny:     0.015em;  /* 12–13px               */
  --ax-tr-body:     0em;      /* 14–16px               */
  --ax-tr-lead:    -0.011em;  /* 19–23px               */
  --ax-tr-head:    -0.018em;  /* 28–33px               */
  --ax-tr-display: -0.024em;  /* 40–48px               */
  --ax-tr-hero:    -0.032em;  /* 57px+                 */

  --ax-lh-flat:    1.0;
  --ax-lh-display: 1.04;
  --ax-lh-head:    1.16;
  --ax-lh-lead:    1.5;
  --ax-lh-body:    1.65;
  --ax-lh-micro:   1.45;

  --ax-fw-thin:      200;
  --ax-fw-regular:   400;
  --ax-fw-medium:    500;
  --ax-fw-semibold:  600;
  --ax-fw-bold:      700;
  --ax-fw-heavy:     800;


  /* ── 7 · SPACE — 4px base, 8px rhythm ──────────────────────────────────── */

  --ax-sp-0:  0;
  --ax-sp-1:  0.125rem;  /*  2 */
  --ax-sp-2:  0.25rem;   /*  4 */
  --ax-sp-3:  0.375rem;  /*  6 */
  --ax-sp-4:  0.5rem;    /*  8 */
  --ax-sp-5:  0.75rem;   /* 12 */
  --ax-sp-6:  1rem;      /* 16 */
  --ax-sp-7:  1.25rem;   /* 20 */
  --ax-sp-8:  1.5rem;    /* 24 */
  --ax-sp-9:  2rem;      /* 32 */
  --ax-sp-10: 2.5rem;    /* 40 */
  --ax-sp-11: 3rem;      /* 48 */
  --ax-sp-12: 4rem;      /* 64 */
  --ax-sp-13: 5rem;      /* 80 */
  --ax-sp-14: 6rem;      /* 96 */
  --ax-sp-15: 8rem;      /* 128 */
  --ax-sp-16: 10rem;     /* 160 */

  --ax-gutter:      clamp(1.25rem, 0.55rem + 3.1vw, 2.5rem);
  --ax-section:     clamp(4rem, 2.2rem + 7.5vw, 8rem);
  --ax-container:   1200px;
  --ax-container-wide: 1440px;
  --ax-container-prose: 68ch;


  /* ── 8 · RADII ─────────────────────────────────────────────────────────── */

  --ax-r-xs:   6px;
  --ax-r-sm:   8px;
  --ax-r-md:  12px;
  --ax-r-lg:  16px;
  --ax-r-xl:  22px;
  --ax-r-2xl: 28px;
  --ax-r-full: 999px;


  /* ── 9 · ELEVATION ─────────────────────────────────────────────────────
     A dark UI cannot lift things with grey shadows — grey on black reads as
     smoke. Elevation here = (surface step) + (edge intensity) + (ambient
     occlusion, near-black + very large blur) + (spectral hairline on top).
     Glow is reserved for things that emit: primary, focus, active.       */

  --ax-el-0: none;
  --ax-el-1: 0 1px 2px rgb(var(--ax-black-rgb)/.55),
             0 2px 10px -4px rgb(var(--ax-black-rgb)/.55);
  --ax-el-2: 0 2px 4px rgb(var(--ax-black-rgb)/.50),
             0 8px 24px -8px rgb(var(--ax-black-rgb)/.70);
  --ax-el-3: 0 4px 8px rgb(var(--ax-black-rgb)/.45),
             0 18px 44px -12px rgb(var(--ax-black-rgb)/.78);
  --ax-el-4: 0 8px 16px rgb(var(--ax-black-rgb)/.42),
             0 34px 80px -20px rgb(var(--ax-black-rgb)/.85);
  --ax-el-5: 0 16px 32px rgb(var(--ax-black-rgb)/.40),
             0 60px 140px -32px rgb(var(--ax-black-rgb)/.90);

  --ax-glow-cy:  0 0 0 1px rgb(var(--ax-cyan-rgb)/.22),
                 0 6px 28px -6px rgb(var(--ax-cyan-rgb)/.38);
  --ax-glow-vi:  0 0 0 1px rgb(var(--ax-violet-rgb)/.24),
                 0 6px 28px -6px rgb(var(--ax-violet-rgb)/.36);
  --ax-glow-spec: 0 10px 34px -10px rgb(var(--ax-cyan-rgb)/.45),
                  0 18px 54px -18px rgb(var(--ax-violet-rgb)/.42);

  /* THE PRISM FOCUS RING. One ring, everywhere, no exceptions. Two layers:
     a dark separator so it survives on a light-ish surface, then the beam. */
  --ax-ring: 0 0 0 2px var(--ax-bg),
             0 0 0 4px rgb(var(--ax-cyan-rgb)/.85),
             0 0 22px -2px rgb(var(--ax-cyan-rgb)/.45);
  --ax-ring-danger: 0 0 0 2px var(--ax-bg),
             0 0 0 4px rgb(var(--ax-danger-rgb)/.85),
             0 0 22px -2px rgb(var(--ax-danger-rgb)/.40);


  /* ── 10 · MOTION ───────────────────────────────────────────────────────
     Six durations, four curves. Anything outside this list is a bug.     */

  --ax-d-instant: 90ms;
  --ax-d-fast:   140ms;
  --ax-d-base:   220ms;
  --ax-d-slow:   340ms;
  --ax-d-slower: 560ms;
  --ax-d-ambient: 900ms;

  --ax-ease:         cubic-bezier(.4, 0, .2, 1);
  --ax-ease-out:     cubic-bezier(.19, 1, .22, 1);    /* expo out  */
  --ax-ease-in-out:  cubic-bezier(.76, 0, .24, 1);
  --ax-ease-accel:   cubic-bezier(.55, 0, 1, .45);
  /* A real spring, sampled to a linear() ramp — used only where a control
     should feel physical: switch knobs, checkbox marks, radio dots. */
  --ax-ease-spring:  linear(
      0, .0088 1.3%, .0347 2.7%, .1252 5.4%, .2739 8.4%, .4409 11.3%,
      .6094 14.2%, .7644 17.2%, .8979 20.5%, .9494 22.2%, .9911 24%,
      1.0239 25.9%, 1.0477 27.9%, 1.0629 30.2%, 1.0695 33%, 1.066 36.6%,
      1.0546 40.2%, 1.0243 47.5%, 1.0028 54.1%, .9938 60.5%, .9962 72.3%,
      1);

  --ax-t-color:  color var(--ax-d-fast) var(--ax-ease),
                 background-color var(--ax-d-fast) var(--ax-ease),
                 border-color var(--ax-d-fast) var(--ax-ease);
  --ax-t-lift:   transform var(--ax-d-base) var(--ax-ease-out),
                 box-shadow var(--ax-d-base) var(--ax-ease-out);


  /* ── 11 · Z-INDEX ──────────────────────────────────────────────────────── */

  --ax-z-behind:   -1;
  --ax-z-base:      0;
  --ax-z-raised:    10;
  --ax-z-sticky:    100;
  --ax-z-header:    200;
  --ax-z-drawer:    300;
  --ax-z-backdrop:  400;
  --ax-z-modal:     410;
  --ax-z-popover:   500;
  --ax-z-tooltip:   600;
  --ax-z-toast:     700;
  --ax-z-grain:     900;


  /* ── 12 · ATMOSPHERE ───────────────────────────────────────────────────
     Grain is not decoration. A 2.4% noise layer is what stops a 9-stop
     gradient from banding on a real 8-bit panel. Never ship without it.  */

  --ax-grain-opacity: .028;
  --ax-caustic-opacity: .42;

  --ax-control-h-sm: 34px;
  --ax-control-h:    44px;
  --ax-control-h-lg: 54px;
  --ax-tap-min:      44px;   /* WCAG 2.5.5 minimum target */
}

/* ── 13 · BREAKPOINTS ────────────────────────────────────────────────────
   Custom properties cannot be used in media queries, so these live here as
   documentation and are written literally throughout the system.
     xs   0      phone portrait
     sm   480    phone landscape
     md   768    tablet portrait
     lg   1024   tablet landscape / small laptop
     xl   1280   desktop
     2xl  1536   wide desktop
   ===================================================================== */

/* ── 14 · REDUCED MOTION ──────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  :root {
    --ax-d-instant: 1ms; --ax-d-fast: 1ms; --ax-d-base: 1ms;
    --ax-d-slow: 1ms;    --ax-d-slower: 1ms; --ax-d-ambient: 1ms;
    --ax-caustic-opacity: 0;
  }
}
