/* Rolina Grains Store: design tokens.
 *
 * This is the only file in the website that may hold a colour, font, size,
 * spacing, motion or z-index literal (Constitution INV-26). Every stylesheet
 * and every component reads from here.
 *
 * The palette is fixed by Law VII-4 and is not a default awaiting override:
 * charcoal and white as the structural neutrals, a teal-green accent anchored
 * at #00997a, and one narrow-use amber reserved for warnings. Nothing else is
 * introduced.
 *
 * Every state also carries wording, weight or a glyph, so no meaning in this
 * interface rests on hue alone and none is lost to a colour-blind reader
 * (WCAG 1.4.1). That matters more here than usual, because green and amber are
 * the classic confusion pair under deuteranopia: the words are what carry the
 * difference, and the colour only reinforces them.
 */

/* ---------------------------------------------------------------------------
   Typeface, self-hosted. Never a font CDN (Constitution 11.3).
   --------------------------------------------------------------------------- */

@font-face {
  font-family: 'IBM Plex Sans';
  src: url('../fonts/ibm-plex-sans-latin-400-normal.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('../fonts/ibm-plex-sans-latin-500-normal.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('../fonts/ibm-plex-sans-latin-600-normal.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('../fonts/ibm-plex-sans-latin-700-normal.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../fonts/ibm-plex-mono-latin-400-normal.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../fonts/ibm-plex-mono-latin-500-normal.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Light only, deliberately.
   *
   * There used to be a full prefers-color-scheme: dark block here, and it was
   * the single worst thing on the live site. It was never designed: it inverted
   * the tokens and hoped, and inversion destroys the one device this whole
   * system rests on. In light, the page is #eef0f2 and a card is #ffffff, and
   * that step IS the boundary, which is why almost every border could be
   * deleted. Inverted, the page was #0f1214 and a card #181d20, a step small
   * enough to disappear, so every boundary went with it and the page collapsed
   * into one flat dark field with nothing outranking anything.
   *
   * It was also forbidden. The Operator's visual system says white is the
   * dominant surface, that entire screens do not become dark backgrounds, and
   * bans full-screen near-black outright. And the Android application has no
   * dark theme at all, so the website having one meant one business wearing two
   * different faces depending on a setting in somebody's operating system.
   *
   * So it is gone rather than repaired. A real dark theme is a design in its
   * own right, not an inversion of this one, and it would need the visual
   * system amended before it could exist. */
  color-scheme: light;

  /* -- The accent ----------------------------------------------------------
   * A vivid teal-green, taken from Brantenna's own POS material rather than
   * from any outside reference. That material sets its green at #2ee59d on
   * charcoal, which is where this family starts.
   *
   * The family then sits at hue 168 rather than the source's 157, and the
   * reason is worth stating because it is a deliberate departure. Green loses
   * its character faster than any other hue as it darkens: at the lightness a
   * 4.5:1 text tone demands, hue 157 is the same green every piece of software
   * on earth uses to say "success", and it read exactly that way once it was
   * on a real button on a real screen. Eleven degrees cooler and the dark end
   * is unmistakably teal while the light end is still unmistakably the
   * Brantenna green. Every tone below is one hue, so the family is coherent;
   * it is simply tuned rather than sampled.
   *
   * It replaced scarlet system-wide (Law VII-4, amended).
   *
   * There are three tones because one cannot do three jobs. A colour bright
   * enough to look like the brand on charcoal is nowhere near 4.5:1 on white,
   * and a colour dark enough for body text on white is a near-black on
   * charcoal. So:
   *
   *   --colour-primary        3.60:1 on white, 3.15:1 on the ground.
   *                           Rules, focus rings, markers, milled edges: every
   *                           non-text use, where WCAG 1.4.11 asks 3:1.
   *   --colour-primary-deep   5.30:1 on white, 4.64:1 on the ground, and white
   *                           on it is 5.30:1. Text and filled button surfaces.
   *   --colour-primary-on-ink 9.38:1 on charcoal. The brand green at full
   *                           strength, for accent text or a mark on a charcoal
   *                           surface, which is the surface Brantenna's own
   *                           material sets this green on.
   *                           The other two are useless there: the anchor
   *                           reaches 4.18:1 and the deep tone only 2.84:1,
   *                           because darker on dark is worse, not better.
   *
   * None of these tones is weakened to make a check pass, and none carries a
   * warning. That is the whole point of the amber below. */
  --colour-primary:       #00997a;   /* the anchor */
  --colour-primary-deep:  #006b56;   /* text and button surfaces */
  --colour-primary-text:  #006b56;
  --colour-primary-hover: #00614e;   /* white on it is 7.45:1 */
  --colour-on-primary:    #ffffff;
  /* A translucent white for a badge sitting ON the accent, such as the basket
     count. Translucent rather than a fixed tone so it holds whichever accent
     surface it lands on. */
  --veil-on-primary:      rgb(255 255 255 / 20%);
  --colour-primary-on-ink: #2ee5c1;  /* the brand green, at full strength */

  /* -- The warning ---------------------------------------------------------
   * One amber, and it appears in exactly four places: a low-stock note, a
   * field that failed validation, the message under it, and the leading edge
   * of an alert. Nowhere else. It is never a call to action, never a brand
   * surface, never a price, and never a confirmation.
   *
   * This separation is the entire reason scarlet was retired rather than
   * recoloured. Scarlet was the accent AND the warning, so "buy this" and
   * "careful" were the same colour on the same screen, and a customer could
   * not tell them apart at a glance. Reusing the new green for warnings would
   * rebuild that collision in a different hue, which is precisely what the
   * Operator instructed against.
   *
   *   --colour-warn       3.63:1 on white, 3.17:1 on the ground. The leading
   *                       edge and the field rule: non-text, WCAG 1.4.11.
   *   --colour-warn-text  5.30:1 on white, 4.64:1 on the ground. The words.
   *   --colour-warn-on-ink 8.72:1 on charcoal.
   *
   * There is no separate error colour. A failure and a caution are the same
   * class of thing to a customer standing at a checkout, and two alarm hues
   * would be one more than this system can justify. */
  --colour-warn:         #c27400;
  --colour-warn-text:    #995c00;
  --colour-warn-on-ink:  #ffb83d;
  --colour-warn-soft:    #fdf3e3;   /* charcoal on it is 13.68:1 */

  /* The deep charcoal surface stays dark in BOTH themes, so whatever sits on it
   * must stay light in both. These two never flip with the theme, which is
   * exactly why they exist rather than the page's ordinary text tones being
   * reused there.
   *
   * The faint tone exists because a grey chosen for white paper turns washed
   * out and dull on charcoal. It is picked against the charcoal and measured
   * there at 5.9:1, so secondary text on the dark band is quieter than the
   * headline and still emphatically legible. */
  --colour-on-deep:       #ffffff;
  --colour-on-deep-faint: #8d979d;
  /* Body copy on a charcoal band, held back from full white so the heading
     above it still leads. Translucent so it works on any charcoal tone. */
  --colour-on-deep-soft:  rgb(255 255 255 / 72%);

  /* Refined slate charcoal, not near-black. #101315 measured 18.6:1 on white, 
     close enough to pure black to read as harsh. This tone still clears 15:1,
     with room to spare over the 4.5:1 body-text floor, while reading as a
     considered charcoal rather than an absence of colour. */
  --colour-ink:           #23272b;
  --colour-ink-mid:       #3b4247;
  --colour-text:          #1c2124;
  /* Both secondary tones are pitched against the PAGE GROUND, not against
     white, because that is the darkest thing they are ever set on. Introducing
     a ground moves the floor for every muted tone in the system by about half a
     point of contrast, and the faint tone quietly fell through it: #667077 read
     5.1:1 on white and 4.43:1 on the ground, which is a real WCAG 1.4.3 failure
     and not a rounding argument. Measured on #eef0f2: 5.7:1 and 4.8:1. Both
     clear on white by a wider margin still. */
  --colour-text-muted:    #454f56;   /* 5.7:1 on the ground, 6.5:1 on white */
  --colour-text-faint:    #525c63;   /* 4.8:1 on the ground, 5.4:1 on white */

  /* -- Ground and surface ---------------------------------------------------
   * The single change that lets almost every rule line in this system be
   * deleted.
   *
   * The page used to be white, so nothing on it could be told apart without
   * drawing a line around it, and the result was a hairline rectangle under
   * every card, every row, every field and every notice: the same clutter the
   * boxes were removed to avoid, redrawn one edge at a time.
   *
   * Now the page carries a soft neutral ground and content sits on white. The
   * step between the two IS the boundary, so a card needs no border, a list
   * needs no divider between its rows, and a bar needs no rule above it. White
   * still dominates, because white is what the content sits on and the content
   * is nearly all of the screen; the ground is what makes it read as paper on
   * a desk rather than as ink on a wall.
   *
   * --colour-page   the desk. Nothing is set directly on it except cards.
   * --colour-surface a card. Pure white, square, no border, no shadow.
   * --colour-inset  a quieter block INSIDE a card: a total, a well, a field. */
  --colour-page:          #e8ebed;
  --colour-surface:       #ffffff;
  --colour-inset:         #f4f6f7;
  --colour-surface-sunk:  #dfe3e6;   /* an inset block pressed or hovered */
  --colour-surface-deep:  #23272b;
  /* One step below the deep surface, for the footer band that carries the
     copyright, the legal links and the maker credit. That block is a different
     class of information from the footer above it, and a genuine change of
     ground is how a page says so. White reads 17.6:1 on it and the softened
     white 9.5:1, so the separation costs no legibility. It has exactly one
     use, and it is not a second charcoal for general work. */
  --colour-surface-deepest: #16191c;

  /* Fields still carry one line, along the bottom, and only there. A filled
     field on a white card cannot reach 3:1 on fill alone (WCAG 1.4.11), and a
     single base rule is the input convention a customer already reads. One
     line under a field is not a box around it. */
  --colour-border:        #d0d6d9;
  --colour-border-strong: #98a1a7;

  --colour-focus:         #00997a;

  /* -- Depth ---------------------------------------------------------------
   * White carries the space, charcoal provides structure, the accent provides
   * emphasis. Depth comes from type, proportion, whitespace and disciplined
   * rule work, never from a gradient, a wash, a glow or a tinted panel. There
   * is deliberately no gradient token in this file, and there must not be one.
   *
   * The only shadow is functional: it appears on the command bar once the page
   * has scrolled beneath it, so the bar reads as being in front of the content
   * rather than drawn on top of it. */
  --rule-firm:   2px;
  --rule-anchor: 3px;

  /* -- Emboss ---------------------------------------------------------------
   * The one depth device permitted on a control, and the reason a button in
   * this system has substance without being a floating card or a thin outline.
   * A filled surface is milled: a single darker tone of its own colour runs
   * along the lower edge, so the control reads as having thickness. Pressing
   * it moves that edge to the top, which is what a real key does when the
   * light stays where it is and the surface goes down. No blur, no spread, no
   * gradient, no glow, the edge is drawn with an inset box-shadow purely
   * because that costs no layout, and it is a hard line, never a fade.
   *
   * Each edge is a darker tonal variation of the surface it sits under, so
   * this introduces no new hue (Law VII-4). */
  --edge-on-primary: #004d3d;   /* under --colour-primary-deep */
  --edge-on-ink:     #12161a;   /* under --colour-ink */
  --edge-on-alt:     #b0b8be;   /* under --colour-surface-alt */

  /* The one deliberate exception to "no gradients, " scoped to exactly one use:
     the active/selected state of a category control. Charcoal into a slightly
     lighter charcoal, left to right, restrained enough that it reads as a
     considered surface, not an effect. Both stops keep white text at 8.7:1 or
     better, and nothing else in this system may reach for this token. */
  --gradient-active: linear-gradient(90deg, #23272b 0%, #383e44 100%);

  /* -- Typography --------------------------------------------------------- */
  --font-display: 'IBM Plex Sans', 'Segoe UI', system-ui, -apple-system, Arial, sans-serif;
  --font-body:    'IBM Plex Sans', 'Segoe UI', system-ui, -apple-system, Arial, sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Consolas, monospace;

  --type-xs:   0.75rem;
  --type-sm:   0.8125rem;
  --type-base: 0.9375rem;
  --type-md:   1.0625rem;
  --type-lg:   1.25rem;
  --type-xl:   1.5rem;
  /* 1.5rem to 2.25rem is a jump of half again, and a headline on a phone wants
     the step in between: at 2.25rem the home page's own headline ran to four
     lines on a 390px screen and took the first half of it. */
  --type-2xl:  1.75rem;
  --type-3xl:  2.25rem;
  --type-4xl:  clamp(2.25rem, 1.4rem + 3.6vw, 3.5rem);

  --leading-tight:   1.15;
  --leading-snug:    1.3;
  --leading-normal:  1.5;
  --leading-relaxed: 1.65;

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

  --tracking-wide: 0.08em;

  /* -- Spacing, on a 4px grid --------------------------------------------- */
  --space-2:   2px;
  --space-4:   4px;
  --space-8:   8px;
  --space-12: 12px;
  --space-16: 16px;
  --space-24: 24px;
  --space-32: 32px;
  --space-48: 48px;
  --space-64: 64px;
  --space-96: 96px;

  /* -- Layout -------------------------------------------------------------- */
  --container-default: 1200px;
  --container-narrow:  720px;
  --container-pad:     var(--space-24);
  --header-height:     72px;

  /* -- Radius ---------------------------------------------------------------
   * Operator amendment to the square-surfaces rule (Law VII-7, XII).
   *
   * Fully right-angled corners everywhere read as mechanical rather than as
   * considered: a drawing of an interface rather than an object. A small
   * radius softens the geometry without becoming decoration. It is deliberately
   * a SMALL move and is not a reversal of the pill retirement, which stands:
   * nothing in this system takes a capsule or half-height radius, because that
   * reads playful and consumer-grade. Six pixels on a control and ten on a card
   * is felt and not noticed, which is the whole intention.
   *
   * There is no pill token, and one must not be added. */
  --radius-xs:   3px;   /* markers, badges, the smallest chips */
  --radius-sm:   6px;   /* buttons, fields, inset blocks, controls */
  --radius-md:  10px;   /* cards */

  /* -- Elevation ------------------------------------------------------------
   * A card does not float. It sits on the ground, and the step from ground to
   * white is what separates it, which is why the card shadow here is a whisper
   * rather than a lift: just enough to keep the edge from looking cut out.
   *
   * The heavier shadow is reserved for something genuinely in front of the
   * page: a bar the content scrolls under, a dialog. That is structure, not
   * decoration (Doctrine 4). */
  --shadow-xs: 0 1px 1px rgb(16 19 21 / 4%);
  --shadow-sm: 0 1px 2px rgb(16 19 21 / 6%);
  --shadow-md: 0 -1px 12px rgb(16 19 21 / 6%);

  /* -- Motion. State transition logic only (Doctrine 5). ------------------- */
  --motion-instant: 90ms;
  --motion-fast:   140ms;
  --ease:          cubic-bezier(0.2, 0, 0.2, 1);

  /* -- Z-index ------------------------------------------------------------- */
  --z-sticky:  50;
  --z-header: 100;
  --z-overlay: 500;
}
