/* =============================================================================
   PlotPDFPro Portal — Design Tokens
   Single source of truth. Derived verbatim from PLOTPDFPRO-DESIGN-LANGUAGE.md v1.0.

   RULES ENFORCED BY tests/PlotPDFPro.Portal.Tests:
     * This is the ONLY file permitted to contain literal colour or length values.
     * Every other stylesheet must reference var(--token).
     * Primitive tokens are never used by components; only semantic tokens are.
   ============================================================================= */

:root {
  /* ---------------------------------------------------------------- primitives
     Raw ramps. Components MUST NOT reference these directly (DL §3.1). */

  /* Paper ramp — light surfaces. Pure white is forbidden (DL §3.2). */
  --primitive-paper-canvas:  #F6F5F2;
  --primitive-paper-surface: #FBFAF8;
  --primitive-paper-raised:  #FDFCFB;
  --primitive-paper-sunken:  #EFEEEA;

  /* Ink ramp — dark surfaces. True black is forbidden (DL §3.3). */
  --primitive-ink-canvas:  #1A1917;
  --primitive-ink-surface: #221F1D;
  --primitive-ink-raised:  #2B2825;
  --primitive-ink-sunken:  #131211;

  /* Neutral ramp (DL §3.4) */
  --primitive-neutral-100-light: #EDECE8;
  --primitive-neutral-200-light: #DEDCD6;
  --primitive-neutral-300-light: #C4C1B9;
  --primitive-neutral-400-light: #9A968D;
  /* Darkened from #75716A for ACP-DESIGN-002. This is --text-tertiary, and the release audit found
     it failing AA everywhere it is used for small text: 4.45:1 on the canvas, 4.18:1 on the sunken
     surface and 4.19:1 on the accent-subtle surface — all under the 4.5:1 that 13px body copy needs.
     It affected the whole footer, every caption and the conversion-mode hints. Now 4.93 / 4.63 / 4.64. */
  --primitive-neutral-500-light: #6E6A63;
  --primitive-neutral-600-light: #55524C;
  --primitive-neutral-900-light: #22201D;

  --primitive-neutral-100-dark: #2F2C29;
  --primitive-neutral-200-dark: #3A3733;
  --primitive-neutral-300-dark: #4A4641;
  --primitive-neutral-400-dark: #6B665F;
  /* Lightened from #8B857C for the same reason on dark: 4.48:1 on the canvas and 3.80:1 on the
     accent-subtle surface. Now 6.07 / 4.79. */
  --primitive-neutral-500-dark: #9D978E;
  --primitive-neutral-600-dark: #A9A39A;
  --primitive-neutral-900-dark: #F2F0EC;

  /* Plot Red — the accent. Deeper and calmer than Adobe's red (DL §3.5). */
  --primitive-red-50:  #FDEAE8;
  --primitive-red-100: #FAD3CF;
  --primitive-red-300: #EE8078;
  --primitive-red-400: #E15C52;
  --primitive-red-500: #D2453A;
  --primitive-red-600: #BE3227;
  --primitive-red-700: #9E2A21;
  --primitive-red-800: #7E231C;

  /* Nature green — success only (DL §3.6). */
  --primitive-green-50:  #EAF6EE;
  --primitive-green-400: #4CA86F;
  --primitive-green-600: #2E7D4F;
  --primitive-green-700: #256641;

  /* State (DL §3.7) */
  --primitive-danger-light:  #B4231F;
  --primitive-danger-dark:   #E8736C;
  /* Darkened from #9A6212 for ACP-DESIGN-001A: badge text is caption-sized and sits on the sunken
     surface, where the old value measured 4.38:1 — under AA. Every other consumer sits on a lighter
     surface and only gains contrast from this (4.87:1 -> 5.83:1 on the default surface). */
  --primitive-warning-light: #8A5710;
  --primitive-warning-dark:  #D9A036;
  --primitive-info-light:    #2A5F8F;
  --primitive-info-dark:     #6BA3D6;

  /* ---------------------------------------------------------------- spacing
     8 px grid. space-1 is the only sub-8 step, for optical corrections (DL §6.1). */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 16px;
  --space-4: 24px;
  --space-5: 32px;
  --space-6: 48px;
  --space-7: 64px;
  --space-8: 96px;
  --space-9: 128px;

  /* ---------------------------------------------------------------- shape (DL §7) */
  --radius-xs:   6px;
  --radius-sm:   8px;
  --radius-md:   12px;
  --radius-lg:   16px;
  --radius-xl:   20px;
  --radius-2xl:  28px;
  --radius-full: 999px;

  /* ---------------------------------------------------------------- typography (DL §5) */
  /* Inter is opportunistic, not shipped: nothing in this repository loads it, so it applies only on
     machines that already have it installed. The stack is ordered so that what customers actually
     get is a deliberate choice rather than an accident — system-ui resolves to Segoe UI Variable on
     Windows and SF Pro on macOS, both of which are technical, high-legibility faces suited to a
     drawing tool. Self-hosting Inter is an owner decision (licence, weight, first-paint cost) and is
     recorded in reports/ACP-DESIGN-001A.md rather than taken here. */
  --font-sans: Inter, system-ui, "Segoe UI Variable", "Segoe UI", -apple-system, sans-serif;
  --font-mono: "JetBrains Mono", "Cascadia Mono", Consolas, ui-monospace, monospace;

  --type-hero-size: 56px;          --type-hero-line: 64px;
  --type-display-size: 40px;       --type-display-line: 48px;
  --type-title1-size: 32px;        --type-title1-line: 40px;
  --type-title2-size: 24px;        --type-title2-line: 32px;
  --type-title3-size: 20px;        --type-title3-line: 28px;
  --type-body-large-size: 17px;    --type-body-large-line: 26px;
  /* Long-form reading, for documents a customer has to read carefully rather than scan. Interface
     body is 15px because it sits beside controls; a privacy policy has no controls next to it and
     15px over several screens is tiring. The 1.65 ratio is looser than the interface 1.6. */
  --type-reading-size: 16px;       --type-reading-line: 27px;
  --type-body-size: 15px;          --type-body-line: 24px;
  --type-caption-size: 13px;       --type-caption-line: 20px;
  --type-caption-strong-size: 12px;--type-caption-strong-line: 16px;
  --type-mono-size: 13px;          --type-mono-line: 20px;

  /* Only two weights exist. 500 is indistinguishable from 400 at 14px (DL §5.2). */
  --weight-regular: 400;
  --weight-strong: 600;

  --tracking-hero: -1.0px;
  --tracking-display: -0.6px;
  --tracking-title1: -0.4px;
  --tracking-title2: -0.2px;
  --tracking-title3: -0.1px;
  --tracking-normal: 0px;
  --tracking-caption-strong: 0.6px;

  /* ---------------------------------------------------------------- motion (DL §9)
     250–350 ms, ease-in-out. No bounce, spring or overshoot anywhere. */
  /* Below the threshold where a delay is perceptible, for the moment a control answers a press.
     Not zero: an instant jump reads as a repaint rather than as a response. */
  --motion-instant: 90ms;
  --motion-fast: 250ms;
  --motion-base: 300ms;
  --motion-slow: 350ms;
  /* The single deliberate exception: the completion ceremony (DL §11.2). */
  --motion-ceremony: 400ms;
  /* The brand-signature delay before the two-leaf mark appears (DL §11.3). */
  --motion-leaf-delay: 250ms;

  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-enter:    cubic-bezier(0.0, 0, 0.2, 1);
  --ease-exit:     cubic-bezier(0.4, 0, 1, 1);
  --ease-linear:   linear;

  /* ---------------------------------------------------------------- weight (ACP-DESIGN-001C)
     Two curves for things that should feel like they have mass. Both stay strictly inside the unit
     square: no value below 0 or above 1, so neither can overshoot or bounce — the difference is
     entirely in how long the movement takes to let go and how hard it arrives.

     --ease-heavy is slow to start and long to settle, for anything large moving across the screen.
     --ease-precise arrives decisively and stops dead, for a control answering a click. A control
     that eases out gently reads as laggy; a drawing that starts instantly reads as weightless. */
  --ease-heavy:   cubic-bezier(0.62, 0.02, 0.16, 1);
  --ease-precise: cubic-bezier(0.32, 0.72, 0, 1);

  /* ---------------------------------------------------------------- layout (DL §6.2) */
  --container-app: 1280px;
  --container-text: 720px;
  --container-reading: 640px;
  /* The reading measure, expressed against the font rather than in pixels. --container-reading is
     640px and the design language claims it yields 65-75 characters; measured against real Turkish
     prose it yields 93, because `ch` is the width of "0" and average prose characters run about
     0.79 of that. 58ch measures 72 characters, and being font-relative it stays correct if the
     type size or the font ever changes. */
  --measure-prose: 58ch;
  --gutter: 24px;
  --page-margin-desktop: 48px;
  --page-margin-tablet: 32px;
  --page-margin-mobile: 20px;

  /* ---------------------------------------------------------------- component sizing (DL §10) */
  --control-height: 44px;
  --control-height-sm: 36px;
  --control-height-lg: 52px;
  --touch-target-min: 44px;
  /* WCAG 2.2 AA (2.5.8) floor, for dense secondary lists such as the footer where a 44px row would
     dominate the page. Primary controls still use --touch-target-min. */
  --touch-target-compact: 24px;
  --focus-ring-width: 2px;
  --focus-ring-offset: 2px;
  --hairline: 1px;

  /* ---------------------------------------------------------------- blueprint (DL §4.3) */
  --blueprint-opacity-open: 0.05;
  --blueprint-opacity-page: 0.03;
  --blueprint-opacity-text: 0.02;
  --blueprint-opacity-dense: 0;
  --blueprint-tile: 640px;

  /* ---------------------------------------------------------------- signature animation (ACP-DESIGN-001B)
     The hero drawing. One cycle carries the vortex, the plan, the elevation and the fade; the phase
     boundaries live in the keyframes, but the length of the whole thing belongs here so the pace can
     be tuned in one place. Long on purpose — this is meant to be noticed, not to demand attention. */
  --signature-cycle: 30000ms;
  /* Two pen weights, well apart. On a real drawing the cut walls are the heaviest line on the sheet
     and everything else is annotation; when the two weights are close the plan reads as a diagram. */
  --signature-stroke: 1;
  --signature-stroke-strong: 2.6;
  /* The frame is cropped rather than shrunk at narrow widths, so the drawing keeps its real scale. */
  --signature-aspect: 16 / 9;
  --signature-aspect-tablet: 5 / 4;
  --signature-aspect-mobile: 4 / 5;
  /* Floor for the hero, so a short window still gives the drawing room to read. */
  --container-hero-min: 520px;
  /* Placeholder height for a section skipped by content-visibility, so the scrollbar does not lie
     about the page length and then correct itself as you scroll. */
  --container-section-estimate: 420px;
  /* Floor for the ribbon schematic on the AutoCAD page. Below this its labels fall under the
     smallest readable size, so the drawing scrolls instead of shrinking further. */
  --container-schematic-min: 420px;
  /* A stencil, not a colour: the black is an alpha channel and never reaches a pixel. It lives here
     anyway, because the rule is that no other stylesheet spells out a colour value — an exception
     "just for masks" is how that rule stops being enforceable. */
  --signature-mask: radial-gradient(ellipse at center, #000 40%, transparent 78%);

  /* ---------------------------------------------------------------- depth (ACP-DESIGN-001C)
     Three planes, separated by very little. The intent is that the eye feels depth without ever
     being able to point at what produces it — so the differences are smaller than they look like
     they should be. Anything more reads as parallax, which is a website effect, not a drawing. */
  --depth-far-opacity: 0.45;
  --depth-mid-opacity: 0.72;
  --depth-near-opacity: 1;
  --depth-far-stroke: 0.75;
  --depth-mid-stroke: 1;
  --depth-near-stroke: 1.25;
  /* How far each plane is carried by the vortex. Nearer sweeps further, which is the only cue that
     does real work — the rest is reinforcement. All three land on a whole turn so the plan forms
     square regardless of which plane a fragment belongs to. */
  --depth-far-sweep: 360deg;
  --depth-mid-sweep: 720deg;
  --depth-near-sweep: 1080deg;

  /* ---------------------------------------------------------------- sheet atmosphere (ACP-DESIGN-001C)
     A drawing sheet rather than a web page, at the threshold of visibility. No texture bitmap, no
     grunge, no sepia, no blueprint blue. Two gradients at 2-3% and a grid at the module the drawing
     itself is built on — which is the point: the page and the drawing share a grid, and that is felt
     rather than seen. */
  --sheet-grid-size: 64px;
  --sheet-grid-opacity: 0.028;
  --sheet-vignette-opacity: 0.035;
  --sheet-mark-length: 14px;
  --sheet-mark-inset: var(--space-3);

  /* ---------------------------------------------------------------- print (ACP-DESIGN-002)
     Paper is not a theme. It is genuinely white, the ink is genuinely black, and the warm neutrals
     that make the screen feel like a drawing sheet only cost toner here. These are the one place in
     the system where pure white and true black are correct — everywhere else they are forbidden. */
  --print-paper: #fff;
  --print-ink: #000;
  --print-ink-secondary: #222;
  --print-ink-tertiary: #444;
  --print-rule-subtle: #ccc;
  --print-rule: #999;
  --print-rule-strong: #666;
  --upload-min-height: 240px;
  --border-dashed-width: 2px;
  --progress-detail-width: 200px;
  --container-ultrawide: 1440px;
  --paper-texture-tile: 220px;
  --paper-texture-opacity: 0.014;
  --container-choice-basis: 180px;

  /* Narrowest an administration card may become before the grid drops a column.
     --container-choice-basis (180px) was used here first and was the wrong basis: it sizes a choice
     tile, not a data card, so a 1366px viewport laid out FIVE 192px columns and a status row needing
     258px spilled 67px into the neighbouring card. 320px is measured from the widest label+badge pair
     the console renders, plus card padding. */
  --container-admin-card-min: 320px;

  /* ================================================================ ACP-DESIGN-001A
     Additions to the v1.0 language, not a replacement for it. Every existing token
     above is untouched; these fill the gaps the component layer had been solving
     with literals. */

  /* ---------------------------------------------------------------- icon sizing
     Icons were passed arbitrary pixel numbers at every call site. Four steps, each
     paired with a control size, so an icon can never be optically wrong for its host. */
  --icon-xs: 14px;   /* inside a badge */
  --icon-sm: 16px;   /* inside a small control */
  --icon-md: 20px;   /* default: body text and medium controls */
  --icon-lg: 24px;   /* large controls and section headers */
  --icon-xl: 32px;   /* empty states */
  --icon-2xl: 56px;  /* the landing mark */

  /* ---------------------------------------------------------------- opacity
     A general scale. Previously only blueprint-specific values existed, so every
     other faded element hard-coded its own number. */
  --opacity-disabled: 0.4;
  --opacity-muted: 0.6;
  --opacity-subtle: 0.75;
  --opacity-scrim: 0.6;
  --opacity-full: 1;

  /* ---------------------------------------------------------------- layering
     Named stacking order. Two overlays fighting over an invented z-index is a class
     of bug that only appears once both are on screen together. */
  --z-base: 0;
  --z-raised: 10;
  --z-sticky: 100;
  --z-header: 200;
  --z-overlay: 300;
  --z-modal: 400;
  --z-toast: 500;

  /* ---------------------------------------------------------------- borders
     Widths, so a component does not invent its own emphasis. */
  --border-width-hairline: 1px;
  --border-width-emphasis: 2px;
  --border-width-marker: 3px;

  /* ---------------------------------------------------------------- skeleton
     Deliberately slower than the interaction motion scale: a loading shimmer that
     moves at UI speed reads as activity rather than as waiting. */
  --skeleton-duration: 1400ms;
  --skeleton-radius: var(--radius-xs);
  --skeleton-line-height: 12px;

  /* ---------------------------------------------------------------- table */
  --table-row-height: 52px;
  --table-cell-padding-x: var(--space-3);
  --table-cell-padding-y: var(--space-3);

  /* ---------------------------------------------------------------- grid
     A named column count so layouts agree on what "half" means. */
  --grid-columns: 12;
  --grid-gap: var(--space-3);
}

/* =============================================================================
   SEMANTIC TOKENS — Light theme (default)
   Components reference only these.
   ============================================================================= */
:root,
:root[data-theme="light"] {
  color-scheme: light;

  --surface-canvas:  var(--primitive-paper-canvas);
  --surface-default: var(--primitive-paper-surface);
  --surface-raised:  var(--primitive-paper-raised);
  --surface-sunken:  var(--primitive-paper-sunken);

  --border-subtle:   var(--primitive-neutral-100-light);
  --border-default:  var(--primitive-neutral-200-light);
  --border-strong:   var(--primitive-neutral-300-light);

  --text-primary:    var(--primitive-neutral-900-light);
  --text-secondary:  var(--primitive-neutral-600-light);
  --text-tertiary:   var(--primitive-neutral-500-light);
  --text-placeholder:var(--primitive-neutral-400-light);
  --text-on-accent:  var(--primitive-paper-surface);

  --accent-default:  var(--primitive-red-600);
  --accent-hover:    var(--primitive-red-700);
  --accent-pressed:  var(--primitive-red-800);
  --accent-subtle:   var(--primitive-red-50);
  --accent-border:   var(--primitive-red-100);
  --accent-gradient-end: var(--primitive-red-500);

  --success-default: var(--primitive-green-600);
  --success-hover:   var(--primitive-green-700);
  --success-subtle:  var(--primitive-green-50);

  /* Commerce status TEXT, distinct from the success/danger surface colours above.
     The coupon components referenced these two names before they existed here, so every render fell
     through to a literal written into components.css. The values below are exactly what that
     fallback produced — #217a50 is rgb(33,122,80) and #b42318 is rgb(180,35,24), both measured on
     production before the move — so this normalisation changes no pixel.

     Stated literally rather than pointing at a primitive because no primitive carries either value:
     --success-default resolves to #2E7D4F and --danger-default to #B4231F, and aligning to those
     WOULD change what a customer sees. Whether these should become primitives or converge on the
     existing ramps is a contrast-measured design decision, and it is still open. */
  --success-text:    #217a50;
  --danger-text:     #b42318;

  --danger-default:  var(--primitive-danger-light);
  --warning-default: var(--primitive-warning-light);
  --info-default:    var(--primitive-info-light);

  --blueprint-stroke: var(--primitive-neutral-400-light);
  /* The signature drawing sits behind the words, so its ordinary line is quieter than body text.
     Structure gets the stronger value — the point of the last phase is that structure survives. */
  --signature-line:        var(--primitive-neutral-300-light);
  --signature-line-strong: var(--primitive-neutral-500-light);
  /* The sheet the page is drawn on, and the marks in its margins (ACP-DESIGN-001C). */
  --sheet-line:  var(--primitive-neutral-400-light);
  --sheet-shade: var(--primitive-neutral-900-light);

  --elevation-1: 0 2px 4px rgba(34, 32, 29, 0.04), 0 4px 12px rgba(34, 32, 29, 0.06);
  --elevation-2: 0 4px 8px rgba(34, 32, 29, 0.06), 0 12px 28px rgba(34, 32, 29, 0.10);
  --elevation-3: 0 8px 16px rgba(34, 32, 29, 0.08), 0 24px 56px rgba(34, 32, 29, 0.14);
  --elevation-top-border: transparent;
}

/* =============================================================================
   SEMANTIC TOKENS — Dark theme
   Not a recolour: the same quality is preserved (DL §16.1).
   ============================================================================= */
:root[data-theme="dark"] {
  color-scheme: dark;

  --surface-canvas:  var(--primitive-ink-canvas);
  --surface-default: var(--primitive-ink-surface);
  --surface-raised:  var(--primitive-ink-raised);
  --surface-sunken:  var(--primitive-ink-sunken);

  --border-subtle:   var(--primitive-neutral-100-dark);
  --border-default:  var(--primitive-neutral-200-dark);
  --border-strong:   var(--primitive-neutral-300-dark);

  --text-primary:    var(--primitive-neutral-900-dark);
  --text-secondary:  var(--primitive-neutral-600-dark);
  --text-tertiary:   var(--primitive-neutral-500-dark);
  --text-placeholder:var(--primitive-neutral-400-dark);
  --text-on-accent:  var(--primitive-ink-canvas);

  /* red-600 does not carry enough contrast on a dark canvas (DL §16.1). */
  --accent-default:  var(--primitive-red-400);
  --accent-hover:    var(--primitive-red-300);
  --accent-pressed:  var(--primitive-red-500);
  --accent-subtle:   var(--primitive-neutral-100-dark);
  --accent-border:   var(--primitive-neutral-200-dark);
  --accent-gradient-end: var(--primitive-red-500);

  --success-default: var(--primitive-green-400);
  --success-hover:   var(--primitive-green-600);
  --success-subtle:  var(--primitive-neutral-100-dark);

  /* SAME VALUES AS THE LIGHT THEME, and deliberately so. The literal these replace lived in
     components.css and was theme-blind, so a dark reader has always seen #217a50 and #b42318. Giving
     the dark theme a different value here would be a visible change, which this task forbids —
     defining them at all is what stops the token resolving to nothing when the dark block wins.
     Adapting them for dark is the open design decision noted in the light theme above. */
  --success-text:    #217a50;
  --danger-text:     #b42318;

  --danger-default:  var(--primitive-danger-dark);
  --warning-default: var(--primitive-warning-dark);
  --info-default:    var(--primitive-info-dark);

  --blueprint-stroke: var(--primitive-neutral-500-dark);
  --signature-line:        var(--primitive-neutral-300-dark);
  --signature-line-strong: var(--primitive-neutral-500-dark);
  --sheet-line:  var(--primitive-neutral-400-dark);
  /* On dark the sheet is lifted with light rather than shaded with dark — the same gesture inverted,
     because a dark wash on a dark ground is invisible and reads as nothing at all. */
  --sheet-shade: var(--primitive-neutral-900-dark);

  /* Shadow alone carries almost no information on dark; a light top border does. */
  --elevation-1: 0 2px 8px rgba(0, 0, 0, 0.36);
  --elevation-2: 0 6px 20px rgba(0, 0, 0, 0.44);
  --elevation-3: 0 12px 40px rgba(0, 0, 0, 0.52);
  --elevation-top-border: var(--primitive-neutral-200-dark);

  /* A thin light stroke reads louder on dark, so blueprint stays at or below 3%. */
  --blueprint-opacity-open: 0.03;
  --blueprint-opacity-page: 0.02;
  --blueprint-opacity-text: 0.015;
}

/* System preference, only when the user has not chosen explicitly. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;

    --surface-canvas:  var(--primitive-ink-canvas);
    --surface-default: var(--primitive-ink-surface);
    --surface-raised:  var(--primitive-ink-raised);
    --surface-sunken:  var(--primitive-ink-sunken);

    --border-subtle:   var(--primitive-neutral-100-dark);
    --border-default:  var(--primitive-neutral-200-dark);
    --border-strong:   var(--primitive-neutral-300-dark);

    --text-primary:    var(--primitive-neutral-900-dark);
    --text-secondary:  var(--primitive-neutral-600-dark);
    --text-tertiary:   var(--primitive-neutral-500-dark);
    --text-placeholder:var(--primitive-neutral-400-dark);
    --text-on-accent:  var(--primitive-ink-canvas);

    --accent-default:  var(--primitive-red-400);
    --accent-hover:    var(--primitive-red-300);
    --accent-pressed:  var(--primitive-red-500);
    --accent-subtle:   var(--primitive-neutral-100-dark);
    --accent-border:   var(--primitive-neutral-200-dark);

    --success-default: var(--primitive-green-400);
    --success-hover:   var(--primitive-green-600);
    --success-subtle:  var(--primitive-neutral-100-dark);

    --danger-default:  var(--primitive-danger-dark);
    --warning-default: var(--primitive-warning-dark);
    --info-default:    var(--primitive-info-dark);

    --blueprint-stroke: var(--primitive-neutral-500-dark);
    --signature-line:        var(--primitive-neutral-300-dark);
    --signature-line-strong: var(--primitive-neutral-500-dark);
    --sheet-line:  var(--primitive-neutral-400-dark);
    --sheet-shade: var(--primitive-neutral-900-dark);

    --elevation-1: 0 2px 8px rgba(0, 0, 0, 0.36);
    --elevation-2: 0 6px 20px rgba(0, 0, 0, 0.44);
    --elevation-3: 0 12px 40px rgba(0, 0, 0, 0.52);
    --elevation-top-border: var(--primitive-neutral-200-dark);

    --blueprint-opacity-open: 0.03;
    --blueprint-opacity-page: 0.02;
    --blueprint-opacity-text: 0.015;
  }
}
