/*
 * Design tokens, Soklae brand system.
 *
 * Single declaration point of the palette: every other sheet reads these names and never writes
 * a colour literal. Values come from the brand guidelines, whose hexadecimal figures are the
 * reference. Where a guideline colour cannot carry text at the 4.5:1 floor, the sheet keeps the
 * guideline value for fills and borders and declares a separate bounded tone for text, rather
 * than silently shifting the brand colour: a fill and a label are not the same problem.
 *
 * Every bounded tone is measured against the DARKEST light surface of the stack, not against
 * white. A value that passes on white and fails on the ivory page background protects nothing,
 * because both backgrounds exist on the same screen. The contrast check of the tooling recomputes
 * all of these pairs and refuses any that falls under the floor.
 *
 * Brand tones come in two families that must not be confused: --ssf-*-tint is an opaque light
 * shade that can carry text, --ssf-*-wash is a translucent veil that takes the colour of whatever
 * sits behind it and is never a text background on its own.
 *
 * The brand green carries text only from 14px upwards and with a semibold weight, through
 * --ssf-brand-text. Below that size, and on any thin icon, text takes --ssf-text: the guidelines
 * reserve the green for backgrounds, borders and buttons.
 */

:root {
	/* Brand green. Backgrounds, borders and buttons. */
	--ssf-primary: #2F3A31;
	--ssf-primary-rgb: 47, 58, 49;
	--ssf-primary-tint: #E3E5DD;
	--ssf-primary-wash: rgba(47, 58, 49, 0.08);

	/* Brand tone bounded to a 4.5:1 contrast against every light surface: it carries the colour
	   AND the legibility, which a raw brand colour does not guarantee. */
	--ssf-brand-text: #2F3A31;

	/* Deep green. The shade a pressed or hovered primary button falls to, and the footer fill.
	   Declared rather than computed: a filter would also darken the label, and a hard coded
	   shade in a component sheet would drift from the palette. */
	--ssf-primary-strong: #1E2620;
	--ssf-on-primary: #F1EEE5;
	/* The same ivory as a triplet. The management rail paints its own links and separators
	   as veils of the text colour over the green fill, and a veil cannot be written from an
	   opaque token: only a triplet lets a rule choose its own alpha. */
	--ssf-on-primary-rgb: 241, 238, 229;

	/* Brass as it may be READ on the brand green. The guideline brass sits at 4.38 against it,
	   which is under the floor, and the eyebrow of the management rail is small uppercase text.
	   Lightened until it clears 4.5 rather than dropped: the brass is what tells the rail apart
	   from the ivory of the labels. */
	--ssf-on-primary-eyebrow: #BFA675;

	/* Brass. Premium details and the production marker, in small doses, never on small text. */
	--ssf-accent: #B49A68;
	--ssf-accent-rgb: 180, 154, 104;
	--ssf-accent-tint: #EEE8DA;
	--ssf-accent-wash: rgba(180, 154, 104, 0.16);
	--ssf-accent-text: #756444;
	--ssf-on-accent: #22271F;

	/* Sage. Soft fills and illustrations, never body text. */
	--ssf-sage: #8FA08E;
	--ssf-sage-rgb: 143, 160, 142;

	/* Ink, slate grey, and a mist grey bounded for text. The guideline mist grey sits at 2.4:1
	   and is a fill tone: a placeholder is text and has to be read. */
	--ssf-text: #22271F;
	--ssf-text-rgb: 34, 39, 31;
	--ssf-text-muted: #5A6157;
	--ssf-text-subtle: #656761;

	--ssf-surface: #FFFFFF;
	--ssf-surface-raised: #FBF9F3;
	--ssf-surface-alt: #F1EEE5;

	/* Rule colour for separators, and a darker one for the boundary of an input, which has to
	   reach 3:1 to be identified as a control. */
	--ssf-border: #DED9CC;
	--ssf-border-strong: #86827B;

	/* Semantic pairs. The base value is the guideline colour and fills or outlines; the -text
	   value is the same hue bounded for a label. A filled semantic banner carries --ssf-text on
	   the amber and --ssf-on-primary on the two darker ones. */
	--ssf-success: #4B7558;
	--ssf-success-rgb: 75, 117, 88;
	--ssf-success-text: #476F53;
	--ssf-warning: #C9A24B;
	--ssf-warning-rgb: 201, 162, 75;
	--ssf-warning-text: #7B632E;
	--ssf-error: #AD5047;
	--ssf-error-rgb: 173, 80, 71;
	--ssf-error-text: #A24C43;
	--ssf-info: #5A7D8C;
	--ssf-info-text: #4D6A77;

	/* A tone measured on the bare card has to be measured again on every wash laid under it: a
	   wash carries the colour of what sits behind it, and the token level calculation sees
	   neither the veil nor the opacity. These two carry a label that sits on its own wash, which
	   is why they exist beside the plain -text pair rather than reusing it. */
	--ssf-success-tint-text: #456B50;
	--ssf-accent-tint-text: #716142;

	/* Chart series, five slots and no sixth. The slot number is written by the server, never
	   deduced from the position of a series in the document, so a series dropped by a filter
	   leaves the colours of the ones that stay exactly where they were.

	   Every value is a guideline colour: the brand green, the slate blue of the information
	   tone, the terracotta of the error tone, the brass and the sage. What was chosen here is
	   their LIGHTNESS: the five sit on a rising ladder of relative luminance, 0.030, 0.058,
	   0.090, 0.145 and 0.212, so that a reader who does not separate a green from a terracotta
	   still separates them by weight. The ladder stops at 0.212 because a fill has to clear 3:1
	   against the darkest light surface of the stack, the green tint, and 0.225 is where that
	   floor sits. Measured worst cases: 10.32, 7.65, 5.90, 4.24 and 3.15 to one.

	   The triplet exists beside each colour because a bar carries a texture as well as a hue,
	   and a texture is a veil the rule has to set its own alpha on.

	   Colour is never the only difference: the sheet gives each slot its own pattern and the
	   legend always carries the words. */
	--ssf-series-1: #263425;
	--ssf-series-1-rgb: 38, 52, 37;
	--ssf-series-2: #2A4856;
	--ssf-series-2-rgb: 42, 72, 86;
	--ssf-series-3: #854133;
	--ssf-series-3-rgb: 133, 65, 51;
	--ssf-series-4: #826633;
	--ssf-series-4-rgb: 130, 102, 51;
	--ssf-series-5: #6C8665;
	--ssf-series-5-rgb: 108, 134, 101;

	/* Environment marker. Demonstration and production share one green, so the accent rule that
	   tells them apart is a colour only production declares. A transparent default keeps the
	   reading rule valid on every other surface. */
	--ssf-env-marker: transparent;

	/* Radii, shadows and spacing of the guidelines. Shadows are low, soft and ink tinted. */
	--ssf-radius-sm: 6px;
	--ssf-radius: 10px;
	--ssf-radius-lg: 16px;
	--ssf-radius-pill: 999px;
	--ssf-shadow: 0 4px 16px rgba(34, 39, 31, 0.08);
	--ssf-shadow-float: 0 12px 32px rgba(34, 39, 31, 0.12);
	--ssf-transition: 160ms ease;

	/* Focus ring of the light surfaces, card and page alike. It is a named token rather than a
	   literal so the runtime check can name what it measured. The brass of the guidelines sits at
	   2.76 against the green tint, under the 3:1 an outline needs, so the ring takes the same hue
	   darkened until it clears every light surface of the stack. The panel carries its own ring,
	   declared per scheme below: one value cannot serve an ivory card and a deep green panel. */
	--ssf-focus-ring: #8C7647;

	/* Ambience layer offset of the wizard panel, 0 to 1, written as an inline style from the step
	   index. Declared here with a neutral default because a var() read that no declaration carries
	   is a defect: with a fallback the choice is never followed, without one the whole declaration
	   is dropped. */
	--ssf-aura-shift: 0;

	--ssf-space-1: 0.25rem;
	--ssf-space-2: 0.5rem;
	--ssf-space-3: 0.75rem;
	--ssf-space-4: 1rem;
	--ssf-space-5: 1.5rem;
	--ssf-space-6: 2rem;
	--ssf-space-7: 3rem;
	--ssf-space-8: 4rem;

	/* Frame of the management area. The rail width and the height of the top bar are read by
	   the sticky offsets of half a dozen rules, so they are one value and not six. */
	--ssf-rail: 264px;
	--ssf-topbar: 56px;

	/* Marcellus carries the headings, Mulish the body. Both ship with the plugin. Marcellus has
	   no Cyrillic coverage, so a Russian heading falls to the serif fallback, which is why the
	   fallback is a classic serif and not a sans. */
	--ssf-font-body: "Mulish", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	--ssf-font-display: "Marcellus", Georgia, "Times New Roman", Times, serif;

	--ssf-size-display: 2.75rem;
	--ssf-size-h1: 2.25rem;
	--ssf-size-h2: 1.75rem;
	--ssf-size-h3: 1.375rem;
	--ssf-size-lead: 1.125rem;
	--ssf-size-body: 1rem;
	--ssf-size-small: 0.875rem;
	--ssf-size-eyebrow: 0.8125rem;
	--ssf-size-caption: 0.75rem;

	--ssf-leading-display: 1.15;
	--ssf-leading-h1: 1.2;
	--ssf-leading-h2: 1.25;
	--ssf-leading-h3: 1.3;
	--ssf-leading-eyebrow: 1.4;
	--ssf-leading-body: 1.6;
	--ssf-leading-small: 1.55;
	--ssf-leading-caption: 1.5;

	/* What is really visible, and how much of it the software keyboard covers. Both carry a
	   fallback that holds with no script at all: 100dvh is what the sheets did before, and nought
	   is the right keyboard height while nobody is measuring. ssf-viewport.js is the only writer. */
	--ssf-viewport-h: 100dvh;
	--ssf-keyboard-h: 0px;

	/* The floor of a touch target, and the measured height of the action bar of the wizard. The
	   second is rewritten by the script that observes the bar: it grows when the state line opens
	   under the buttons, so a figure written into a rule would be wrong half the time. */
	--ssf-tap: 44px;
	--ssf-actions-h: 84px;

	/* Bootstrap owns the --bs- prefix. Remapping the handful of variables that carry its own
	   blue is what stops a focus ring or a link from arriving in a colour the brand never uses.
	   These are set on :root rather than per component because Bootstrap reads them from the
	   element that owns the control, which is not always one of our containers. */
	--bs-primary: #2F3A31;
	--bs-primary-rgb: 47, 58, 49;
	--bs-link-color: #2F3A31;
	--bs-link-color-rgb: 47, 58, 49;
	--bs-link-hover-color: #1E2620;
	--bs-border-color: #DED9CC;
	--bs-border-radius: 10px;
	--bs-focus-ring-color: rgba(47, 58, 49, 0.25);
	--bs-body-font-family: "Mulish", system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

/*
 * Wizard panel, two schemes. The card and the page stay light in both: what the toggle commands is
 * the panel, not a dark mode, which is why prefers-color-scheme is not read here and why the wizard
 * never carries .ssf-supports-dark.
 *
 * Signature panel is a gradient, so every tone is bounded against BOTH of its stops, the lighter
 * one being the binding case. The light scheme panel is a flat sage on purpose: a gradient would
 * give a range of luminances and each tone would have to hold against two of them, while a flat
 * fill gives one measurable value. On that sage no colour lighter than the fill reaches 3:1, white
 * itself topping out at 2.77, so everything meant to be seen there is darker than its background.
 *
 * The signature values are also attached to the bare component: the attribute is written server
 * side and again by the anti-flash block before first paint, but a panel with no tones at all is a
 * worse failure than a panel in the wrong one.
 */
.ssf-wizard,
.ssf-wizard[data-ssf-scheme="signature"] {
	--ssf-panel-from: #2F3A31;
	--ssf-panel-to: #1E2620;
	--ssf-on-panel: #F1EEE5;
	--ssf-on-panel-muted: #C8CEC4;
	--ssf-on-panel-soft: #C0C1B8;
	--ssf-on-panel-eyebrow: #B69D6D;
	--ssf-on-panel-line: #7D8279;
	--ssf-panel-meter-done: #B49A68;
	--ssf-panel-meter-now: #F1EEE5;
	--ssf-panel-card: rgba(241, 238, 229, 0.06);
	--ssf-panel-quote: rgba(30, 38, 32, 0.55);
	--ssf-panel-filet: #B49A68;
	--ssf-focus-ring-panel: #B69D6D;
}

.ssf-wizard[data-ssf-scheme="light"] {
	--ssf-panel-from: #8FA08E;
	--ssf-panel-to: #8FA08E;
	--ssf-on-panel: #22271F;
	--ssf-on-panel-muted: #22271F;
	--ssf-on-panel-soft: #22271F;
	--ssf-on-panel-eyebrow: #1E2620;
	--ssf-on-panel-line: #485047;
	--ssf-panel-meter-done: #2F3A31;
	--ssf-panel-meter-now: #22271F;
	/* Opaque here, not a veil: the help card has to be a surface of its own so the ink on it is
	   measured against the card and not against the sage, which would leave it at 5.51 instead of
	   14.47 and would move with whatever the panel does. */
	--ssf-panel-card: #FBF9F3;
	--ssf-panel-quote: #E3E5DD;
	/* The brass rule renders 1.02 on the sage and simply disappears, so the light scheme rule is
	   the brand green. */
	--ssf-panel-filet: #2F3A31;
	--ssf-focus-ring-panel: #2F3A31;
}

/* Production carries the brass rule and the brass label. The green does not move: two greens a
   few points apart would read as the same screen, and the guidelines hold one primary. */
.ssf-env-production {
	--ssf-env-marker: #B49A68;
}

/* Demonstration carries the slate blue. The two markers are never told apart by colour alone:
   the rule sits beside a pill that names the environment in words. */
.ssf-env-demonstration {
	--ssf-env-marker: #5A7D8C;
}

/* The dark stack, and nothing carries the class that opens it since 0.44.0.
   The management area did, and following the system there was the wrong answer: an area drawn in
   deep green on a machine set to dark is a screen no mockup shows and no operator asked for. The
   block stays, measured and ready, because the day a surface of ours wants a dark stack it wants
   this one and not one invented again from scratch, and because the contrast check of the tooling
   keeps measuring every pair in it. Nothing here is reachable today. */
@media (prefers-color-scheme: dark) {
	.ssf-supports-dark {
		/* Dark surfaces descend from the deep green of the guidelines rather than from a neutral
		   charcoal, so the palette stays recognisable. Text rises to the ivory, which is the pair
		   the guidelines already prescribe on green. */
		--ssf-surface: #1E2620;
		--ssf-surface-raised: #28322A;
		--ssf-surface-alt: #151A16;

		--ssf-text: #F1EEE5;
		--ssf-text-rgb: 241, 238, 229;
		--ssf-text-muted: #C2C8BE;
		--ssf-text-subtle: #9A9E94;

		/* On a dark surface the brand green IS the background, so the fill that has to be seen
		   moves to the sage and takes ink rather than ivory, which is the second pairing the
		   guidelines prescribe. Keeping the deep green here would leave a primary button at a
		   ratio of 1.2 against the card it sits on, which is to say invisible. */
		--ssf-primary: #8FA08E;
		--ssf-primary-rgb: 143, 160, 142;
		--ssf-primary-tint: #2D372F;
		--ssf-primary-wash: rgba(143, 160, 142, 0.14);
		--ssf-primary-strong: #AFBBAE;
		--ssf-on-primary: #22271F;
		--ssf-on-primary-rgb: 34, 39, 31;
		/* On a dark surface the rail fill IS the sage, so the eyebrow turns and darkens instead
		   of lightening. The light value would sit at 1.4 against that fill. */
		--ssf-on-primary-eyebrow: #3B3218;

		--ssf-brand-text: #90A18F;
		--ssf-accent-text: #B49A68;
		--ssf-accent-tint: #303429;
		--ssf-accent-wash: rgba(180, 154, 104, 0.20);
		--ssf-on-accent: #22271F;

		--ssf-border: #3A443B;
		--ssf-border-strong: #738175;

		/* The two tint surfaces turn dark here, so the darkened brass of the light palette falls
		   to 2.8 against them. The ring rises to the guideline brass, which clears every dark
		   surface of the stack. */
		--ssf-focus-ring: #B49A68;

		/* The semantic tones rise with the text: on a dark surface they are read as an outline or
		   as a label, never as a fill, so the fill value and the label value converge. */
		--ssf-success: #7FB08D;
		--ssf-success-rgb: 127, 176, 141;
		--ssf-success-text: #7FB08D;
		--ssf-success-tint-text: #7FB08D;
		--ssf-accent-tint-text: #B49A68;
		--ssf-warning: #C9A24B;
		--ssf-warning-rgb: 201, 162, 75;
		--ssf-warning-text: #C9A24B;
		--ssf-error: #E08A80;
		--ssf-error-rgb: 224, 138, 128;
		--ssf-error-text: #E08A80;
		--ssf-info: #8FB4C4;
		--ssf-info-text: #8FB4C4;

		/* The series ladder turns over on a dark surface: the binding floor is no longer the
		   green tint of the light stack but the brass tint of the dark one, the LIGHTEST surface
		   here, so the five rise instead of falling. The ladder is kept, 0.245 to 0.718 of
		   relative luminance, and so is the order of the hues, which is what makes a chart read
		   the same after the mode flips. Measured worst cases against the brass tint: 3.47,
		   4.17, 5.26, 7.00 and 9.04 to one. */
		--ssf-series-1: #689266;
		--ssf-series-1-rgb: 104, 146, 102;
		--ssf-series-2: #689DB6;
		--ssf-series-2-rgb: 104, 157, 182;
		--ssf-series-3: #DD988A;
		--ssf-series-3-rgb: 221, 152, 138;
		--ssf-series-4: #DDBF89;
		--ssf-series-4-rgb: 221, 191, 137;
		--ssf-series-5: #D6DFD3;
		--ssf-series-5-rgb: 214, 223, 211;

		--ssf-shadow: 0 4px 16px rgba(0, 0, 0, 0.45);
		--ssf-shadow-float: 0 12px 32px rgba(0, 0, 0, 0.55);

		--bs-link-color: #90A18F;
		--bs-link-color-rgb: 144, 161, 143;
		--bs-link-hover-color: #C2C8BE;
		--bs-border-color: #3A443B;
		--bs-focus-ring-color: rgba(143, 160, 142, 0.35);
	}
}
