/* ---------------------------------------------------------------------------
   The token file. Every value the site is allowed to use lives here.

   Before this file existed, colour was the only system in the repo: six brand
   tokens declared halfway down enhancements.css. Everything else was decided
   per screen. One page rendered font sizes 11 12 13 14 15 16 17 17.6 18 20 22
   24 32 40 45 and 55, with weights 200 400 500 600 700 mixed arbitrarily, and
   there was no spacing token at all. That is not a style problem, it is the
   reason the site reads as three stylesheets rather than one voice.

   Loaded FIRST in index.html so every sheet below can consume it. Note that
   style.css declares its own :root at line 50 with the same specificity, so it
   wins on source order for any name it repeats. That is why --main-color-one
   is repointed in style.css itself rather than redefined here: two :root blocks
   fighting over one name is the disease, not the cure.
--------------------------------------------------------------------------- */

:root {
  /* ── colour ───────────────────────────────────────────────────────────
     Brand green split by role (audit P1). #95B935 on white measures 2.3:1,
     so the single most important number on every card was unreadable to
     roughly a fifth of visitors. White text ON the green fails just as badly
     at 2.27:1, which is what the navbar CTA was until now.

     --brand-ink   text and icons on a light surface        5.0:1
     --brand-fill  fills, pills and bars, dark ink on top   7.9:1 with on-fill
  */
  --brand-ink: #57761C;
  --brand-fill: #95B935;
  --brand-on-fill: #101425;

  /* Audit P16: the badges used four unrelated stock Material colours in one
     row next to brand green. These two are the rest of the same hue, a pale
     surface and its border, so a badge can be a tinted outline without
     introducing a fifth palette. */
  --brand-tint: #EEF4DE;
  --brand-line: #C9DC96;

  /* Unavailable: sold, rented, archived. Slate, never red. Nothing went
     wrong, the listing is simply gone. */
  --state-muted: #4A5160;

  /* Every divider on the site. Replaces the five different near-greys in use
     today: rgba(112,112,712,.1), #eee, #f0f0f0, #e3e4de, #e8e9e3. */
  --rule: #E4EAD3;
  --rule-strong: var(--brand-line);

  /* Bootstrap's .text-success measures 3.16:1. These clear AA on white. */
  --state-danger: #B3261E;
  --state-success: #1E6B3A;

  /* Control boundaries need 3:1 against their surface to satisfy WCAG 1.4.11.
     The theme's #d4d4d4 field border measures 1.6:1. */
  --field-line: #8A8F85;

  /* ── type ─────────────────────────────────────────────────────────────
     Eight steps with real jumps. Nothing between them is legal. The old set
     had 15 and 16 doing the same job, and a 17.6 that is not a decision. */
  --fs-100: 0.75rem;   --lh-100: 1.4;    /* 12 */
  --fs-200: 0.875rem;  --lh-200: 1.5;    /* 14 */
  --fs-300: 1rem;      --lh-300: 1.65;   /* 16, body */
  --fs-400: 1.125rem;  --lh-400: 1.4;    /* 18 */
  --fs-500: 1.375rem;  --lh-500: 1.3;    /* 22 */
  --fs-600: 1.75rem;   --lh-600: 1.2;    /* 28 */
  --fs-700: 2.25rem;   --lh-700: 1.15;   /* 36 */
  --fs-800: 3rem;      --lh-800: 1.05;   /* 48, renders exactly once: home H1 */

  /* Three weights is why a page reads as one voice. Five is why this one read
     as three. 200 and 800 have no downloaded file, so they were already being
     faked or silently ignored by the browser. */
  --fw-regular: 400;
  --fw-semibold: 600;
  --fw-bold: 700;

  /* ── type: the two families ───────────────────────────────────────────
     Moved here from style.css, which is where they used to be declared and
     the one thing the token file did not own. A file that defines every step,
     weight and role of the type system except which typeface renders it is
     not the token file, it is most of the token file. style.css now carries a
     pointer where the declarations used to be.

     The family rule is one sentence, and it is the whole answer to "which
     font is this": anything that NAMES a thing takes the heading font,
     anything you READ AS SENTENCES takes the body font. A section title, a
     card title and a twelve-pixel eyebrow are all names, so all three are
     Poppins regardless of size. A paragraph, a caption and a form hint are
     sentences, so they are Open Sans. Size does not enter into it, which is
     why the footer column head stopped being the one label on the site set
     in the body font at the same size as an eyebrow set in the heading one.
  */
  --heading-font: "Poppins", sans-serif;
  --body-font: "Open Sans", sans-serif;

  /* ── type: roles ──────────────────────────────────────────────────────
     The steps above are the vocabulary. These are the grammar.

     A step scale alone does not stop a site drifting, and this one did not:
     every component still chose its own step, so an h2 rendered at 28 on the
     home page, 22 on a listing, 18 on /contact and 12 in the footer, and the
     footer's was the only heading on the site in the body font. Four sizes
     and two families for one element is what "the fonts feel inconsistent"
     actually measures out to.

     Nine roles. A component picks a ROLE, never a step, and the role decides
     size, weight, line height, tracking and family together, so the same job
     cannot render two ways on two pages.

       display        the home hero, and nothing else on the site
       page-title     the h1 of a page, every page
       section-title  an h2 opening a major block of the page body
       panel-title    the heading of a panel, card group or aside
       card-title     the name of a single card
       body-lg        lead copy, the sentence under a title
       body           paragraphs
       small          captions, meta, roles under names
       eyebrow        the uppercase label above or over a group

     Only the role tokens move on a phone (see the media query at the foot of
     this file). The steps stay put, because a step is a measurement and a
     role is a decision, and it is the decision that should change when the
     screen is 390px wide.
  */
  --t-display-font: var(--heading-font);
  --t-display-size: var(--fs-800);
  --t-display-lh: var(--lh-800);
  --t-display-weight: var(--fw-bold);
  --t-display-track: -0.02em;

  --t-page-title-font: var(--heading-font);
  --t-page-title-size: var(--fs-700);
  --t-page-title-lh: var(--lh-700);
  --t-page-title-weight: var(--fw-bold);
  --t-page-title-track: -0.02em;

  --t-section-title-font: var(--heading-font);
  --t-section-title-size: var(--fs-600);
  --t-section-title-lh: var(--lh-600);
  --t-section-title-weight: var(--fw-bold);
  --t-section-title-track: -0.01em;

  --t-panel-title-font: var(--heading-font);
  --t-panel-title-size: var(--fs-500);
  --t-panel-title-lh: var(--lh-500);
  --t-panel-title-weight: var(--fw-semibold);
  --t-panel-title-track: -0.01em;

  --t-card-title-font: var(--heading-font);
  --t-card-title-size: var(--fs-400);
  --t-card-title-lh: var(--lh-400);
  --t-card-title-weight: var(--fw-semibold);
  --t-card-title-track: 0;

  --t-body-lg-font: var(--body-font);
  --t-body-lg-size: var(--fs-400);
  --t-body-lg-lh: 1.6;
  --t-body-lg-weight: var(--fw-regular);

  --t-body-font: var(--body-font);
  --t-body-size: var(--fs-300);
  --t-body-lh: var(--lh-300);
  --t-body-weight: var(--fw-regular);

  --t-small-font: var(--body-font);
  --t-small-size: var(--fs-200);
  --t-small-lh: var(--lh-200);
  --t-small-weight: var(--fw-regular);

  /* One tracking value for every eyebrow on the site. It used to be 0.12em in
     the footer and on the browse labels, 0.14em on the 404 code and 0.16em on
     the hero, which is three decisions where there is one label. */
  --t-eyebrow-font: var(--heading-font);
  --t-eyebrow-size: var(--fs-100);
  --t-eyebrow-lh: var(--lh-100);
  --t-eyebrow-weight: var(--fw-semibold);
  --t-eyebrow-track: 0.12em;

  /* ── space ────────────────────────────────────────────────────────────
     Nothing on this site uses an odd pixel value again. The theme shipped
     pd-top-60/80/85/92/100: 85 and 92 are not measurements, they are drift. */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 48px;
  --sp-8: 64px;
  --sp-9: 80px;
  --sp-10: 96px;

  /* ── the four spacings that decide whether the page breathes ──────────
     The scale above is the vocabulary. These four are the grammar: every
     grid, every section, every card and every rail reads one of them rather
     than picking a number. They are declared here so a phone can change all
     four in one media query at the bottom of this file, which is the only
     honest way to say "mobile is a recompose, not a shrink".

     Before this, .single-feature carried `margin-bottom: 24px` and the grid
     it sat in was a Bootstrap flex row. A block child's bottom margin has
     nowhere to go inside a stretched flex column, so it was dropped: cards
     on /property measured card0 bottom 1198, card1 top 1198. Zero. A grid
     that owns its own gap cannot lose one. */
  --grid-gap: var(--sp-5);      /* between cards in any grid */
  --rail-gap: var(--sp-4);      /* between cards in a swipeable rail */
  --card-pad: 20px;             /* a card's inner padding */
  --sp-section: var(--sp-8);    /* above and below every section */

  /* Anything that scrolls to a heading has to clear the fixed header, or the
     heading it just scrolled to is underneath it. */
  --scroll-offset: calc(var(--nav-h) + var(--sp-5));

  /* ── radius ───────────────────────────────────────────────────────────
     The radius of a child is never larger than its parent's, and no element
     changes radius on hover or focus. */
  --r-sm: 4px;    /* inputs, small controls */
  --r-md: 8px;    /* panels, images inside a card */
  --r-lg: 12px;   /* detail gallery, modals */
  /* Benchmarked against propertyfinder.bh: their cards, search bar and filter
     pills all sit at a generous radius with a 1px hairline and no shadow at
     all, and the whole page reads calmer for it. Ours were 8px with a shadow
     each, which is the 2019 SaaS default. */
  --r-xl: 20px;   /* cards, the hero search panel */
  --r-full: 999px; /* pills, chips, segmented controls, avatars */

  /* ── motion ───────────────────────────────────────────────────────────
     Hover 180ms, image reveals 260ms, the nav drawer 350ms. Nothing else
     moves. A skeleton is honest because it says data is in flight; an
     entrance animation on data that already arrived is theatre. */
  --dur-fast: 120ms;
  --dur: 180ms;
  --dur-slow: 260ms;
  --ease-out: cubic-bezier(0.2, 0, 0, 1);

  /* ── elevation ────────────────────────────────────────────────────────
     Two layers, one light source. The tight contact shadow stays put while
     the ambient one grows and the hairline warms, which is how a real object
     lifts off a table. Never rgba(0,0,0,x): the shadow takes its hue from
     the ink colour so it sits in the same world as the type. */
  --shadow-rest: 0 1px 2px rgba(16, 20, 37, 0.06), 0 0 0 1px rgba(16, 20, 37, 0.05);
  --shadow-lift: 0 2px 4px rgba(16, 20, 37, 0.06), 0 12px 24px -8px rgba(16, 20, 37, 0.16), 0 0 0 1px var(--brand-line);

  /* ── targets and chrome ───────────────────────────────────────────────
     The navbar is position:fixed at z-index 9999, so a keyboard-focused
     element needs to clear it or the ring lands underneath and is invisible. */
  --tap: 44px;

  /* Two rows on desktop: a slim identity row and the row of search intents
     under it. Anything that has to clear the fixed header (a sticky aside, a
     focus ring, a heading being scrolled to) reads --nav-h, so it is the one
     place the height is stated.

     It used to be stated and then contradicted. --nav-h said 112px while the
     header measured 117, and on a phone it said 56 while the header measured
     60, because the rows were sized by their padding and the token was a
     guess at what that would come to. Everything that offsets from the header
     was therefore four or five pixels wrong on every page.

     The two rows now carry these heights explicitly and --nav-h is their sum,
     so the number cannot drift from the thing it measures. */
  --nav-row-identity: 64px;
  --nav-row-links: 48px;
  --nav-h: calc(var(--nav-row-identity) + var(--nav-row-links));

  /* The bottom tab bar on a phone, plus whatever the device reserves for its
     home indicator. */
  --tabbar-h: 56px;
  --tabbar-total: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px));
}

/* The header collapses to one row, and the intents row it loses is replaced
   by the bottom tab bar rather than by a drawer. 768 rather than 992: the six
   intents still fit as text on a small tablet, and a tab bar on a 900px-wide
   screen would be a phone pattern on something that is not a phone. */
@media (max-width: 767.98px) {
  :root {
    --nav-row-identity: 56px;
    --nav-row-links: 0px;

    /* Only the two display sizes move. Body copy does not shrink on a phone. */
    --fs-700: 1.75rem;
    --fs-800: 2rem;

    /* Mobile is a recompose, not a shrink, and that applies to type as much
       as to grids. The heading ladder is five distinct steps at both widths:

         desktop   48  36  28  22  18
         phone     32  28  22  18  16

       display and page-title come down on their own, because they read
       --fs-800 and --fs-700 and those two steps are already overridden above.
       The three below have to be reassigned by hand, and they are reassigned
       rather than scaled: each one drops to the next real step, so a phone
       never renders a size that is not in the scale. Without this the ladder
       collapsed, because section-title reads --fs-600, which does not move,
       so a page title and the section under it both measured 28. */
    --t-section-title-size: var(--fs-500);
    --t-section-title-lh: var(--lh-500);
    --t-panel-title-size: var(--fs-400);
    --t-panel-title-lh: var(--lh-400);
    --t-card-title-size: var(--fs-300);
    --t-card-title-lh: var(--lh-400);

    /* 16 between cards, 40 between sections, 16 inside a card. A phone is
       385px of usable width, so a 24px gutter on both sides of a grid is 12%
       of the screen spent on nothing. */
    --grid-gap: var(--sp-4);
    --card-pad: var(--sp-4);
    --sp-section: 40px;
  }
}
