/**
 * Design tokens.
 *
 * The single source of truth for every value in the design system. Nothing
 * below this file contains a raw colour, font stack, spacing value or duration
 * — components reference these custom properties instead.
 *
 * Loaded first after the webfont. It also declares the cascade layer order for
 * the whole theme, so the order stylesheets happen to load in cannot change how
 * they cascade.
 *
 * See docs/design-system.md.
 */

@layer ajp.tokens, ajp.base, ajp.layout, ajp.components, ajp.utilities;

@layer ajp.tokens {

	:root {

		/* ==================================================================
		 * 1. COLOUR
		 *
		 * Six colours do the work. Everything else is a role that points at
		 * one of them. Every combination used for text has been checked
		 * against WCAG AA; the ratios are recorded beside each role.
		 * ================================================================== */

		/* --- Palette ---------------------------------------------------- */

		/*
		 * Paper is very slightly warm rather than #fff. Against the cool grey
		 * of the machinery photography it reads as printed stock rather than
		 * as an unstyled browser default, and it stops the large white areas
		 * of the page glaring next to the dark bands.
		 */
		--ajp-paper: #fbfaf8;
		--ajp-surface: #f2f1ed;        /* card panels, alternating sections */
		--ajp-surface-hover: #eae8e3;

		/*
		 * Ink is a neutral near-black, not the blue-black the theme used
		 * before. Two different near-blacks (#14171a chrome and #0f172a
		 * neutral-900) were in use and the difference was visible where a
		 * dark band met a dark heading.
		 */
		--ajp-ink: #16181a;
		--ajp-ink-line: #2f3438;       /* hairline on ink */

		--ajp-body: #43484c;           /* 8.87:1 on paper, 8.19:1 on surface */
		--ajp-muted: #63686c;          /* 5.40:1 on paper, 4.99:1 on surface */
		--ajp-on-ink: #b9bdc0;         /* 9.41:1 on ink */
		--ajp-on-ink-muted: #8b9094;   /* 5.52:1 on ink */

		--ajp-line: #dedcd6;           /* hairline on paper */
		--ajp-line-strong: #c6c3bb;    /* hairline that needs to be seen */

		/*
		 * One red. Unchanged from the identity, and unchanged from the live
		 * site's Astra palette, so nothing about the brand shifts.
		 *
		 * Red is used for: primary button fills, the slash motif, hover and
		 * active states, and nothing else. It is never used as text on ink
		 * (3.62:1) or on a card surface (4.35:1) — both fail AA, which is
		 * what settles the question rather than taste.
		 */
		--ajp-red: #dd183b;            /* 4.72:1 on paper; white on it 4.92:1 */
		--ajp-red-hover: #b8112f;      /* white on it 6.65:1 */
		--ajp-red-ink: #ffffff;

		--ajp-white: #ffffff;

		/* --- Roles ------------------------------------------------------ */

		--ajp-color-bg: var(--ajp-paper);
		--ajp-color-surface: var(--ajp-surface);
		--ajp-color-surface-hover: var(--ajp-surface-hover);
		--ajp-color-inverse-bg: var(--ajp-ink);

		--ajp-color-heading: var(--ajp-ink);
		--ajp-color-text: var(--ajp-body);
		--ajp-color-muted: var(--ajp-muted);
		--ajp-color-on-inverse: var(--ajp-on-ink);
		--ajp-color-on-inverse-heading: var(--ajp-white);
		--ajp-color-on-inverse-muted: var(--ajp-on-ink-muted);

		--ajp-color-line: var(--ajp-line);
		--ajp-color-line-strong: var(--ajp-line-strong);
		--ajp-color-line-inverse: var(--ajp-ink-line);

		--ajp-color-brand: var(--ajp-red);
		--ajp-color-brand-hover: var(--ajp-red-hover);
		--ajp-color-brand-contrast: var(--ajp-red-ink);

		--ajp-color-link: var(--ajp-ink);
		--ajp-color-link-hover: var(--ajp-red);

		/* --- Focus ------------------------------------------------------ */

		--ajp-focus-color: var(--ajp-ink);
		--ajp-focus-color-inverse: var(--ajp-white);
		--ajp-focus-width: 2px;
		--ajp-focus-offset: 2px;

		/* ==================================================================
		 * 2. TYPOGRAPHY
		 *
		 * One family. Hierarchy comes from size, weight and space — not from
		 * setting things in condensed uppercase.
		 * ================================================================== */

		--ajp-font-fallback: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
		--ajp-font: "InterVariable", "Inter", var(--ajp-font-fallback);

		/*
		 * ss02 is Inter's disambiguation set. It matters here more than it
		 * would on most sites: machine titles are model numbers, and
		 * "MLT627", "TB014 1.5" and "LX885" have to be transcribable at a
		 * glance. cv05 gives the lowercase l a tail so it cannot be read as
		 * a 1 or a capital I.
		 */
		--ajp-font-features: "ss02" 1, "cv05" 1, "calt" 1;

		/*
		 * Type scale. Each step interpolates between a 390px and a 1440px
		 * viewport, so components need no typographic breakpoints at all.
		 *
		 *   step       390px    1440px
		 *   display     40        60     hero H1
		 *   h1          32        52     page titles
		 *   h2          26        40     section titles
		 *   h3          20        28     sub-headings
		 *   card        18        20     machine card title
		 *   lead        17        19     supporting copy
		 *   body        16        16
		 *   meta        14        14     metadata, counts, captions
		 *   label       12        12     eyebrows, column headings, status
		 *   price       24        30
		 */
		--ajp-text-display: clamp(2.5rem, 2.06rem + 1.81vw, 3.75rem);
		--ajp-text-h1: clamp(2rem, 1.536rem + 1.905vw, 3.25rem);
		--ajp-text-h2: clamp(1.625rem, 1.3rem + 1.333vw, 2.5rem);
		--ajp-text-h3: clamp(1.25rem, 1.064rem + 0.762vw, 1.75rem);
		--ajp-text-card: clamp(1.125rem, 1.079rem + 0.19vw, 1.25rem);
		--ajp-text-lead: clamp(1.0625rem, 1.016rem + 0.19vw, 1.1875rem);
		--ajp-text-body: 1rem;
		--ajp-text-meta: 0.875rem;
		--ajp-text-label: 0.75rem;
		--ajp-text-price: clamp(1.5rem, 1.361rem + 0.571vw, 1.875rem);

		--ajp-weight-regular: 400;
		--ajp-weight-medium: 500;
		--ajp-weight-semibold: 600;
		--ajp-weight-bold: 700;

		--ajp-leading-display: 1.05;
		--ajp-leading-heading: 1.14;
		--ajp-leading-snug: 1.3;
		--ajp-leading-body: 1.65;

		/*
		 * Large type needs negative tracking to hold together; small caps-y
		 * labels need positive tracking to stay legible. Nothing in between
		 * is tracked at all.
		 */
		--ajp-tracking-display: -0.03em;
		--ajp-tracking-heading: -0.022em;
		--ajp-tracking-snug: -0.01em;
		--ajp-tracking-none: 0;
		--ajp-tracking-label: 0.08em;

		--ajp-measure: 66ch;
		--ajp-measure-lead: 46ch;

		/* ==================================================================
		 * 3. SPACING
		 *
		 * A 4px-based scale. Components pick a step by name; equivalent
		 * relationships in different components use the same step, which is
		 * what the semantic aliases below exist to enforce.
		 * ================================================================== */

		--ajp-space-1: 0.25rem;  /*  4px */
		--ajp-space-2: 0.5rem;   /*  8px */
		--ajp-space-3: 0.75rem;  /* 12px */
		--ajp-space-4: 1rem;     /* 16px */
		--ajp-space-5: 1.5rem;   /* 24px */
		--ajp-space-6: 2rem;     /* 32px */
		--ajp-space-7: 3rem;     /* 48px */
		--ajp-space-8: 4rem;     /* 64px */
		--ajp-space-9: 6rem;     /* 96px — the value --ajp-section-y reaches at 1440 */

		/* --- Semantic relationships ------------------------------------- */

		--ajp-space-eyebrow: var(--ajp-space-3);      /* eyebrow  -> heading */
		--ajp-space-heading-copy: var(--ajp-space-4); /* heading  -> supporting copy */
		--ajp-space-head-content: var(--ajp-space-6); /* section head -> grid/content */
		--ajp-space-copy-cta: var(--ajp-space-6);     /* copy     -> call to action */
		--ajp-space-para: var(--ajp-space-4);         /* paragraph-> paragraph */
		--ajp-space-meta-title: var(--ajp-space-2);   /* metadata -> title */
		--ajp-space-card-pad: var(--ajp-space-5);     /* card internal padding */
		--ajp-space-block: var(--ajp-space-7);        /* sub-block within a section */

		--ajp-gap-grid: var(--ajp-space-6);           /* machine card grids */
		--ajp-gap-grid-dense: var(--ajp-space-5);     /* sold, gallery, related */
		--ajp-gap-inline: var(--ajp-space-4);         /* buttons, inline clusters */

		/* --- Section rhythm ---------------------------------------------
		 *
		 * Three levels, one system. No component declares its own section
		 * padding: it picks a level. Before this there were four different
		 * paddings in play and the page read as a stack of unrelated blocks.
		 *
		 *                 390px    1440px
		 *   tight           40        64
		 *   default         56        96
		 *   loose           72       128
		 * ---------------------------------------------------------------- */

		--ajp-section-y: clamp(3.5rem, 2.571rem + 3.81vw, 6rem);
		--ajp-section-y-tight: clamp(2.5rem, 1.943rem + 2.286vw, 4rem);
		--ajp-section-y-loose: clamp(4.5rem, 3.2rem + 5.333vw, 8rem);

		/*
		 * The body of an inner page runs tighter than a homepage band.
		 *
		 * The homepage is a sequence of separate bands, where generous space is
		 * what separates one from the next. An inner page is one document sitting
		 * directly under the header band — the band already does the separating,
		 * so the same measurement below it reads as a gap to scroll past before
		 * the content starts. Its own token, so tuning inner pages cannot drift
		 * the homepage. The header band itself keeps --ajp-section-y-tight.
		 */
		--ajp-page-y: clamp(2rem, 1.63rem + 1.52vw, 3rem);

		/* ==================================================================
		 * 4. LAYOUT
		 *
		 * Declared once. No component redefines container width or gutters.
		 *
		 *   gutter   20px at 390  ->  40px at 1440
		 * ================================================================== */

		--ajp-container-max: 75rem;    /* 1200px — unchanged from the live site */
		--ajp-container-narrow: 44rem; /*  704px, prose */
		--ajp-container-wide: 90rem;   /* 1440px */
		--ajp-gutter: clamp(1.25rem, 0.786rem + 1.905vw, 2.5rem);

		/* ==================================================================
		 * 5. BORDERS, RADIUS, ELEVATION
		 * ================================================================== */

		--ajp-border-width: 1px;
		--ajp-border: var(--ajp-border-width) solid var(--ajp-color-line);

		/*
		 * One radius, everywhere. 2px is deliberate: square enough to match
		 * the hard geometry of the logo, soft enough that the page reads as
		 * printed material rather than as cut plate. Reversible in one line.
		 */
		--ajp-radius: 2px;

		/*
		 * One shadow, and it is used exactly twice — on the two navigation
		 * panels, which overlap photography and cannot be separated from it
		 * by a border. Nothing else on the site casts a shadow.
		 */
		--ajp-shadow-panel: 0 1px 2px rgb(22 24 26 / 0.08), 0 12px 28px rgb(22 24 26 / 0.10);

		/* ==================================================================
		 * 6. CONTROLS
		 * ================================================================== */

		--ajp-control-height-sm: 2.5rem;  /* 40px */
		--ajp-control-height: 3rem;       /* 48px */
		--ajp-control-height-lg: 3.5rem;  /* 56px */
		--ajp-control-pad-x: var(--ajp-space-5);

		/* ==================================================================
		 * 7. MACHINERY
		 *
		 * 4:3 because every source photograph is 4:3 and machines are framed
		 * with the boom or ROPS near the top edge — a 16:10 crop cuts them.
		 * See docs/design-system.md §15.4.
		 * ================================================================== */

		--ajp-card-media-ratio: 4 / 3;
		--ajp-sold-dim: 0.88;

		/* ==================================================================
		 * 8. MOTION
		 *
		 * Every duration routes through these so the reduced-motion rule in
		 * base.css can neutralise animation in one place.
		 * ================================================================== */

		--ajp-duration-fast: 120ms;
		--ajp-duration-base: 200ms;
		--ajp-ease: cubic-bezier(0.2, 0, 0.2, 1);

		/* ==================================================================
		 * 9. Z-INDEX
		 *
		 * A named ladder. Never write a bare z-index in a component.
		 * ================================================================== */

		--ajp-z-raised: 10;
		--ajp-z-dropdown: 100;
		--ajp-z-header: 300;
		--ajp-z-skip-link: 600;
	}
}
