/*
 * CS DISPLAY — THE TOKEN CONTRACT
 *
 * This file is the deliverable. Components and layouts read from it and
 * nothing else; cloning to acting / filmmakers / beauty is a token swap.
 *
 * WHY THIS LIST IS LONGER THAN A COLOUR PALETTE
 * ---------------------------------------------
 * If tokens only carry colour, four skins are four colour swaps, and the
 * gate for this plugin exists to catch exactly that. A skin has to be able
 * to change the SHAPE of the design, so the contract carries:
 *
 *   - the type scale RATIO, not just sizes
 *   - the spacing base unit, so density is a skin decision
 *   - border weight, and whether the design uses rules at all
 *   - radius, letter-spacing, label case
 *   - the card image ratio and its share of card height
 *
 * Those are what make "editorial" and "industrial" different design systems
 * rather than the same one in different paint.
 *
 * REGISTER
 * --------
 * A printed casting directory, or an architecture firm's project index.
 * Typographic, restrained, generous whitespace. Photography carries the
 * visual weight; chrome is nearly invisible. Values here are chosen against
 * that and not against what a SaaS dashboard looks like.
 *
 * Every value below is a DEFAULT. skins/{name}/tokens.json overrides any of
 * them, and the skin loader emits the override block after this file.
 */

:root {

  /* ---- TYPE ------------------------------------------------------------
   * Scale steps are shipped computed rather than calculated in CSS: calc()
   * cannot do exponentiation, and a skin that wants a 1.333 ratio instead of
   * 1.2 must be able to say so in JSON without a build step.
   */
  --cs-font-display: Georgia, 'Times New Roman', serif;
  --cs-font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
  --cs-font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --cs-scale-ratio: 1.25;          /* documented for skin authors */

  --cs-text-2xs: 0.694rem;
  --cs-text-xs:  0.8rem;
  --cs-text-sm:  0.9rem;
  --cs-text-md:  1rem;
  --cs-text-lg:  1.25rem;
  --cs-text-xl:  1.563rem;
  --cs-text-2xl: 1.953rem;
  --cs-text-3xl: 2.441rem;
  --cs-text-4xl: 3.052rem;

  --cs-leading-tight: 1.15;
  --cs-leading-snug: 1.35;
  --cs-leading-normal: 1.6;

  --cs-weight-normal: 400;
  --cs-weight-medium: 500;
  --cs-weight-bold: 600;

  --cs-tracking-tight: -0.02em;
  --cs-tracking-normal: 0;
  --cs-tracking-wide: 0.08em;

  /* Labels are the design's connective tissue — every stat row, chip and
   * field name. Making their case and tracking tokens is most of why the
   * skins read as different systems. */
  --cs-label-transform: uppercase;
  --cs-label-tracking: var(--cs-tracking-wide);
  --cs-label-weight: var(--cs-weight-bold);
  --cs-label-size: var(--cs-text-2xs);

  --cs-measure: 68ch;              /* max line length for prose */

  /* ---- SPACE -----------------------------------------------------------
   * One base unit; every step derives from it. A skin sets density by
   * changing the unit alone.
   */
  --cs-space-unit: 0.25rem;
  --cs-space-1: calc(var(--cs-space-unit) * 1);
  --cs-space-2: calc(var(--cs-space-unit) * 2);
  --cs-space-3: calc(var(--cs-space-unit) * 3);
  --cs-space-4: calc(var(--cs-space-unit) * 4);
  --cs-space-5: calc(var(--cs-space-unit) * 5);
  --cs-space-6: calc(var(--cs-space-unit) * 6);
  --cs-space-8: calc(var(--cs-space-unit) * 8);
  --cs-space-12: calc(var(--cs-space-unit) * 12);
  --cs-space-16: calc(var(--cs-space-unit) * 16);
  --cs-space-24: calc(var(--cs-space-unit) * 24);

  /* ---- SURFACE ---------------------------------------------------------
   * "ink" and "paper" rather than "text" and "background": the register is
   * print, and the naming keeps that in front of whoever edits a skin.
   */
  --cs-paper: #ffffff;
  --cs-paper-2: #f7f7f5;
  --cs-paper-3: #eeeeea;
  --cs-ink: #16161a;
  --cs-ink-2: #55555c;
  /* ink-3 carries every label, caption and count on the site, so it has to
   * read: 4.5:1 against paper AND paper-2 (WCAG 1.4.3, small text). The
   * first palette was 3.4–3.7:1 on every skin — elegant, and failing. */
  --cs-ink-3: #6f6f78;
  --cs-rule: #dcdcd8;
  --cs-accent: #16161a;
  --cs-accent-ink: #ffffff;

  /* Reserved, deliberately sparse. Colour is not how this design signals. */
  --cs-positive: #1d6b3f;
  --cs-caution: #8a5a00;
  --cs-critical: #8a2018;

  /* ---- LINE AND SHAPE --------------------------------------------------
   * A skin that sets --cs-border-width to 0 becomes a whitespace-only design
   * with no rules anywhere. That is a structural change, not a paint change,
   * and it is why border width is a token.
   */
  --cs-border-width: 1px;
  --cs-border-width-heavy: 2px;
  --cs-radius: 0;
  --cs-radius-pill: 0;

  --cs-shadow-none: none;
  --cs-shadow-raised: none;        /* the register does not use shadow */

  /* ---- CARD ------------------------------------------------------------
   * THE ANTI-DATING-APP CONSTRAINT, EXPRESSED AS A TOKEN.
   *
   * A card is two grid rows, photograph then data, and the photograph's row
   * is exactly --cs-card-image-share of the card's height. The data decides
   * how tall the card is; the photograph is cropped to its share of that. If
   * a card reads face-first the fix is to lower the share, and it applies to
   * every skin at once.
   *
   * A photo grid of attractive people with a contact button is visually
   * indistinguishable from a dating app unless this is fought deliberately.
   */
  --cs-card-image-share: 0.5;

  /* The same share as the card's two grid rows. CSS cannot compute a flex
   * value — calc() refuses fr — so the skin loader derives each skin's rows
   * from its share, and this default must say what the share above says.
   * tests-cs-display.php holds the two together. */
  --cs-card-rows: 1fr 1fr;

  /* The floor under the photograph: without it a card with almost nothing to
   * say shrinks its image to a strip. Landscape on purpose — a sparse card
   * should be short, not a tall portrait with a caption. */
  --cs-card-image-floor: 5 / 4;

  /* The portrait on a profile page, and any lone image framed outside a card. */
  --cs-card-image-ratio: 4 / 5;
  --cs-card-min-width: 15rem;
  --cs-card-gap: var(--cs-space-6);

  --cs-gallery-ratio: 1 / 1;
  --cs-avatar-ratio: 1 / 1;

  /* ---- MOTION ----------------------------------------------------------*/
  --cs-duration: 120ms;
  --cs-easing: cubic-bezier(0.2, 0, 0.2, 1);

  /* ---- FOCUS -----------------------------------------------------------
   * Focus is a token so a skin cannot accidentally make it invisible, and
   * so contrast is auditable in one place.
   */
  --cs-focus-width: 2px;
  --cs-focus-offset: 2px;
  --cs-focus-color: var(--cs-ink);

  /* ---- BREAKPOINTS -----------------------------------------------------
   * Documented here for skin authors and for the JS drawer; CSS media
   * queries cannot read custom properties, so components restate them.
   * Mobile first: 375 is the design target, not the fallback.
   */
  --cs-bp-sm: 23.4375rem;  /* 375 */
  --cs-bp-md: 46rem;       /* 736 */
  --cs-bp-lg: 64rem;       /* 1024 */
  --cs-bp-xl: 90rem;       /* 1440 */

  --cs-container: 76rem;
  --cs-drawer-width: 22rem;
  /* The filters as a SIDEBAR beside the grid, above the large breakpoint.
   * Narrower than the drawer: at 22rem the grid kept two columns at 1280px,
   * and a directory is read across, not down. */
  --cs-sidebar-width: 15rem;
  --cs-portrait-column: 18rem;

  /* A hairline that survives a skin setting --cs-border-width to 0. Used
   * only where the line carries MEANING rather than structure — the empty
   * ring on an unverified badge, for instance, where losing the outline
   * loses the statement. em-relative so it scales with type. */
  --cs-hairline: 0.0625em;

  /* WCAG 2.2 · 2.5.8 Target Size (Minimum) is 24x24 CSS px. This is a floor
   * from the specification, not a style choice, so it is a token to keep it
   * out of component files rather than to make it themeable. Raising it is
   * fine; lowering it below 24 fails the criterion. */
  --cs-target-min: 32px;

  /* WCAG 2.5.5 Target Size (Enhanced) is 44x44 — the level a submit button on
   * a phone should meet, since it is the one control a visitor must hit. */
  --cs-target-touch: 44px;
}

@media (prefers-reduced-motion: reduce) {
  :root { --cs-duration: 0ms; }
}

/*
 * Dark is a skin concern, not a component concern. A skin that wants dark
 * redefines ink and paper; nothing downstream changes. This block only
 * covers the default skin.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-cs-skin-locked]) {
    --cs-paper: #121214;
    --cs-paper-2: #1a1a1d;
    --cs-paper-3: #232327;
    --cs-ink: #f2f2f0;
    --cs-ink-2: #a8a8b0;
    --cs-ink-3: #83838a;
    --cs-rule: #33333a;
    --cs-accent: #f2f2f0;
    --cs-accent-ink: #121214;
  }
}
