/* The site's design system: one file, linked from the head of every public
   page.
 *
 * It used to live inside the landing page's <style> block, which meant the
 * landing page was the only page that had it. Every other public page fell back
 * to the literal values each component carried "just in case", so the booking
 * page painted itself from a second palette of its own and ignored a reader who
 * had asked their system for a dark page — the tokens that answer that question
 * were never delivered to it.
 *
 * A token defined here is a token every public page has. A component that
 * paints with these names is dark-ready and on-system the day it is written,
 * and there is one place to change a colour, a radius, or a shadow.
 *
 * Admin is deliberately not a client of this file. It is the owner's tool, not
 * the guest's site, and it has its own dark shell in admin/shell.go. */

:root {
  color-scheme: light;

  /* ---- Colour -------------------------------------------------------- */

  --nyland-cream: #f6f1e8;
  --nyland-paper: #fffaf1;
  --nyland-ink: #20302a;
  /* Measured against every surface they are drawn on. The muted grey read
     4.26 against the page and the rust 4.07, both under the 4.5 that small
     text owes a reader; between them they carry the fact labels, the footer,
     and the hero's opening line, so the shortfall was on every page. */
  --nyland-muted: #5c6b62;
  --nyland-pine: #29483c;
  --nyland-sage: #d7dfd2;
  --nyland-linen: #ebe0cf;
  --nyland-rust: #955737;

  /* Ink that sits on top of a --nyland-pine fill. It is not simply white: in a
     dark page the pine becomes the light colour and this becomes dark. */
  --nyland-on-pine: #fffaf1;

  /* Pine is the accent, and an accent is for things the size of a button. A
     whole hero or quote card filled with it is fine on a cream page and
     glaring on a dark one, where pine has to become the light colour to stay
     legible as an accent — so the site's largest solid cards would turn into
     slabs of mint in the middle of a dark page.
   *
   * The panel is therefore its own role: pine while the page is cream, a deep
   * surface a shade above the page while the page is dark. A card that fills
   * itself with --nyland-panel reads the same way in both. */
  --nyland-panel: #29483c;
  --nyland-on-panel: #fffaf1;
  --nyland-on-panel-muted: rgba(255,250,241,.78);
  --nyland-on-panel-border: rgba(255,250,241,.28);
  --nyland-on-panel-border-strong: rgba(255,250,241,.5);
  --nyland-on-panel-hover: rgba(255,250,241,.14);

  --nyland-page: linear-gradient(180deg, var(--nyland-cream), #eef3ea 72%, #e6eee4);
  --nyland-surface: rgba(255,250,241,.72);
  --nyland-surface-strong: rgba(255,250,241,.78);
  --nyland-border: rgba(32,48,42,.1);
  --nyland-border-strong: rgba(32,48,42,.18);
  --nyland-hover: rgba(215,223,210,.64);
  --nyland-shadow: rgba(32,48,42,.08);
  --nyland-shadow-strong: rgba(32,48,42,.16);
  --nyland-overlay: rgba(15,20,18,.42);

  /* A refusal the guest has to read — a rejected date, a field that came back
     wrong. Rust is the site's warm accent; this is the same hue turned up until
     it reads as a correction rather than a decoration. */
  --nyland-alarm: #9b3429;
  --nyland-alarm-edge: #b54d3f;
  --nyland-affirm: #245034;
  --nyland-affirm-surface: #e4f3e7;
  --nyland-affirm-edge: #a8cfb0;

  /* ---- Calendar days --------------------------------------------------
     One day in the availability calendar is in exactly one of five conditions,
     and each is a fill, an edge, and an ink that have to hold their meaning in
     both schemes. They live here rather than in the calendar because the
     calendar was painting them as literal light-scheme hexes: on a dark page
     an available day ended up as near-white lettering on a near-white fill,
     which is to say the days a guest could actually book were the only thing
     on the page they could not see. */
  --nyland-day-open-surface: #f2fbf3;
  --nyland-day-open-edge: var(--nyland-affirm-edge);
  --nyland-day-taken-surface: #fbf1ef;
  --nyland-day-taken-edge: #efc4bc;
  --nyland-day-taken-ink: #80574f;
  --nyland-day-short-surface: #f4f1ea;
  --nyland-day-short-ink: #736d60;
  --nyland-day-past-ink: #787163;
  --nyland-day-picked-surface: var(--nyland-panel);
  --nyland-day-picked-end-surface: #3f6a58;
  --nyland-day-weeks-edge: #c9922b;
  --nyland-day-weeks-glow: #e0b64a;

  /* The veil and edge that lift a photograph off the page. Text drawn over a
     photograph stays light in both schemes, because a photograph is a
     photograph either way. */
  --nyland-photo-veil: linear-gradient(180deg, rgba(32,48,42,.04), rgba(32,48,42,.26));
  --nyland-photo-edge: rgba(255,250,241,.36);
  --nyland-photo-ink: rgba(255,250,241,.9);
  --nyland-photo-scrim: rgba(15,20,18,.38);
  /* Darker than the page's usual overlay: the photograph viewer draws a caption
     and a close button on top of it, over a page that is itself a wall of
     photographs. */
  --nyland-photo-backdrop: rgba(10,14,12,.82);

  /* ---- Radius -------------------------------------------------------- */

  --nyland-radius-xs: .7rem;
  --nyland-radius-sm: 1rem;
  --nyland-radius-md: 1.25rem;
  --nyland-radius-lg: 1.5rem;
  --nyland-radius-xl: 2rem;
  --nyland-radius-pill: 999px;
  /* What a card sized in --nyland-radius-xl collapses to once the screen is
     narrow enough that the corner is a large fraction of the card. */
  --nyland-radius-xl-narrow: 1.4rem;

  /* ---- Elevation ----------------------------------------------------- */

  --nyland-elevation-1: 0 18px 50px var(--nyland-shadow);
  --nyland-elevation-2: 0 24px 80px var(--nyland-shadow-strong);
  /* Reserved for the one element a page lifts furthest off the surface: the
     opening photograph. */
  --nyland-elevation-3: 0 30px 80px var(--nyland-shadow-strong);

  /* ---- Spacing ------------------------------------------------------- */

  /* The gutter is the distance between the page's content and the edge of the
     screen. Every full-width band on a public page uses it, which is what makes
     their left edges line up as a reader scrolls past them.
   *
   * It is one token, and it is the token that knows about the narrow screen —
   * see the breakpoint below. Every band used to carry its own
   * `@media (max-width: 820px)` rule swapping in the narrow value, which is
   * three places to forget: the site header forgot, and floated itself on a
   * gutter of its own invention, so the wordmark stood 49px inside the heading
   * underneath it on a desktop and 9px inside it on a phone. */
  /* The widest the page's content is allowed to get. Past this the gutter grows
     instead of the content, so a band centres itself rather than stretching a
     line of text across a 2560px display.
   *
   * 76rem is not a new number: it is the cap the site header used to carry
     alone, as `min(100% - 2rem, 76rem)`. That was somebody's measure for the
     site, applied to the one band that was not full-bleed — which is why the
     header and the page disagreed at every width. Keeping the measure and
     giving it to the gutter makes every band agree instead. */
  --nyland-measure: 76rem;
  --nyland-gutter: max(clamp(1rem, 6vw, 5rem), (100% - var(--nyland-measure)) / 2);
  --nyland-gutter-narrow: 1rem;
  --nyland-band: clamp(2rem, 6vw, 4rem);
  --nyland-gap-sm: .5rem;
  --nyland-gap: 1rem;
  --nyland-gap-lg: clamp(2rem, 5vw, 5rem);
  /* The site header is fixed, so a page's first band starts below where it
     comes to rest rather than underneath it.
   *
   * One value, because there is one bar: it rests at the same height and stands
   * the same 68px tall at 320px as it does at 1440. There used to be a second,
   * narrower token beside this one, justified by the header sitting 4px higher
   * on a phone — which it did, because the header gave itself a different top
   * on a narrow screen for no reason but that it also gave itself a different
   * width there. */
  --nyland-header-clearance: 5.5rem;

  /* ---- Type ---------------------------------------------------------- */

  --nyland-font: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* A display line is set tight, but never tighter than the type is tall: at
     these sizes a leading below 1 lands the descenders of one line in the
     ascenders of the next as soon as the headline wraps, which it does on the
     first narrow screen. */
  --nyland-display-leading: 1.02;
  --nyland-display-tracking: -.07em;
  --nyland-display: clamp(2.7rem, 7vw, 6rem);
  --nyland-display-lg: clamp(4rem, 11vw, 9rem);
  --nyland-heading: clamp(1.7rem, 4vw, 2.5rem);
  --nyland-body-leading: 1.55;

  /* The eyebrow above a heading. It appears on the hero, the gallery, the
     footer, the booking hero, and the quote card, and each of those had picked
     its own size, weight, and tracking. */
  --nyland-eyebrow-size: .78rem;
  --nyland-eyebrow-weight: 800;
  --nyland-eyebrow-tracking: .16em;

  /* An eyebrow is a caption. An eyebrow that is a heading is still a heading,
     and the two were the same small uppercase grey — so "Estimate", the h2
     naming the quote card, was indistinguishable from "Reservation", the
     caption sitting above the form beside it. A reader scanning the page had
     nothing to tell the name of a region from a label inside one.
   *
   * A heading keeps the eyebrow's size and tracking, because these are small
   * cards and a 2.5rem heading inside one is not the answer. It takes the
   * full-strength ink instead of the muted one, and a rule under it: the label
   * belongs to what follows, and the rule is what says so. */
  --nyland-eyebrow-heading-rule: 1px;
  --nyland-eyebrow-heading-gap: .5rem;
}

/* The one place the gutter changes. A band that paints itself with the token
   is inset correctly on a phone without knowing that phones exist. */
@media (max-width: 820px) {
  :root { --nyland-gutter: var(--nyland-gutter-narrow); }
}

@media (prefers-color-scheme: dark) {
  :root {
    color-scheme: dark;

    --nyland-cream: #101613;
    --nyland-paper: #18201c;
    --nyland-ink: #e6ece7;
    --nyland-muted: #9aaba1;
    /* Pine is the accent, so in a dark page it has to be the light colour: the
       same role, not the same hex. */
    --nyland-pine: #8fc0a9;
    --nyland-sage: #24312b;
    --nyland-linen: #2a2f28;
    --nyland-rust: #d99873;

    --nyland-on-pine: #0d1411;

    /* The panel keeps its role rather than its hue: a surface a shade above the
       page, with the page's own ink on it. */
    --nyland-panel: #1d2c25;
    --nyland-on-panel: #e6ece7;
    --nyland-on-panel-muted: rgba(230,236,231,.72);
    --nyland-on-panel-border: rgba(230,236,231,.16);
    --nyland-on-panel-border-strong: rgba(230,236,231,.34);
    --nyland-on-panel-hover: rgba(230,236,231,.1);

    --nyland-page: linear-gradient(180deg, var(--nyland-cream), #131b17 72%, #16201b);
    --nyland-surface: rgba(230,236,231,.05);
    --nyland-surface-strong: rgba(24,32,28,.82);
    --nyland-border: rgba(230,236,231,.12);
    /* Measured against the page's own top gradient stop, #101613: at .2 this
       blended to rgb(59,63,60), a 1.6:1 contrast against the page — the
       secondary hero button's outline read as loose text next to the primary
       button's fill, and every outlined control sharing this token (the
       currency pills, the calendar day outlines) was in the same shortfall.
       .4 blends to a 3.4:1 contrast, above the 3:1 WCAG 1.4.11 asks of a
       non-text control boundary. */
    --nyland-border-strong: rgba(230,236,231,.4);
    --nyland-hover: rgba(230,236,231,.09);
    --nyland-shadow: rgba(0,0,0,.5);
    --nyland-shadow-strong: rgba(0,0,0,.62);
    --nyland-overlay: rgba(4,8,6,.62);

    --nyland-alarm: #f0a094;
    --nyland-alarm-edge: #c96b5b;
    --nyland-affirm: #a8dcb6;
    --nyland-affirm-surface: #1c3325;
    --nyland-affirm-edge: #356244;

    /* Each day keeps its role rather than its hue: green still means open and
       the warm shade still means somebody else has it, but both are now fills
       a light ink can sit on. */
    --nyland-day-open-surface: #1c3325;
    --nyland-day-taken-surface: #33201c;
    --nyland-day-taken-edge: #6b3f36;
    --nyland-day-taken-ink: #f0a094;
    --nyland-day-short-surface: #232b27;
    --nyland-day-short-ink: #9aaba1;
    --nyland-day-past-ink: #9aaba1;
    --nyland-day-picked-end-surface: #274c3c;
    --nyland-day-weeks-edge: #e0b64a;
    --nyland-day-weeks-glow: #c9922b;

    --nyland-photo-veil: linear-gradient(180deg, rgba(4,8,6,.1), rgba(4,8,6,.45));
    --nyland-photo-edge: rgba(230,236,231,.14);
  }
}

/* ---- Base ------------------------------------------------------------ */

/* Every in-page anchor on the site — the hero's button into the first section,
   each entry in the navigation and the mobile menu, the skip link — used to
   scroll its target to the very top of the viewport, which is where the fixed
   header is. The heading a reader had just asked for landed underneath it, and
   on a narrow screen, where the header is a third of the way down what a phone
   shows, the section arrived headless: a reader who tapped "The house" got the
   first fact and no sign of what it was a fact about.
 *
   Padding the scroll container rather than each target means an anchor added
   later is right by default, instead of being right only if somebody remembers
   to give it a scroll margin of its own. */
html { scroll-padding-top: calc(var(--nyland-header-clearance) + var(--nyland-gap-sm)); }

/* The skip link's destination. It is focusable so that skipping actually moves
   focus rather than only the scroll position, and it draws no ring of its own:
   a rectangle around the whole page is not feedback, and the page having
   visibly moved is. */
#main-content:focus { outline: none; }

/* Without this a padded element sized in percentages of the viewport is wider
   than the number it was given. The fixed site header is exactly that, so it
   used to hang seven pixels off each edge of a 320px screen. */
*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--nyland-page);
  color: var(--nyland-ink);
  font-family: var(--nyland-font);
}

/* Every public page is the same three things in the same order: the header, the
   one <main> the skip link points at, and the footer. Saying so here is what
   puts the footer at the foot of a short page — the 404 left 195px of empty
   page below it — and it only works because the header and footer are siblings
   of <main> rather than the first and last things inside it.
 *
 * They used to be inside it on the landing page and on both enquiry pages,
 * which made "Skip to content" land on a container whose first child was the
 * navigation the reader had just asked to skip, and nested the banner and
 * contentinfo landmarks inside the main one. */
body { display: flex; flex-direction: column; }
body > main { flex: 1 0 auto; }

/* Not every page is a set of full-width bands, and the ones that are not are
   deliberate. The 404, the 429 and both enquiry pages centre a narrow column —
   48rem, 44rem — inside the measure rather than filling it, because each is one
   short piece of prose or one form, and a form set across 1216px is a form
   nobody can follow along a line of. They will therefore not line up with the
   header above them or the footer below them, and that is the intent: a card
   floating on the page, not a band of it. Left here so the next person
   measuring gutters does not "fix" them into agreement. */
