/* The app's public website. Its own sheet, not the booking pages': those
   wear the colours of whichever bunkhouse is using them, and this is the
   app speaking for itself. Nothing is set under 0.875rem (14px). */

@layer reset, base, layout, components;

@layer reset {
  *, *::before, *::after { box-sizing: border-box; }
  body { margin: 0; }
  img, svg { display: block; max-inline-size: 100%; block-size: auto; }
  h1, h2, h3, p, ul { margin: 0; }
  ul { padding: 0; }
}

@layer base {
  :root {
    color-scheme: light dark;
    /* The app's own green, the colour a bunkhouse has before it chooses
       one, and the colour of the mark (bunkhouse.Mark) beside the name. */
    --accent: #00873f;
    --accent-hover: #00823d;
    --on-accent: #ffffff;
    --sea: #0b5a7d;
    --fixed: #8a4b08;
    --ink: #1b1b1b;
    --muted: #575757;
    --paper: #fbfaf7;
    --stone: #f1efe9;
    --line: color-mix(in oklab, var(--ink) 12%, var(--paper));
    --focus: color-mix(in oklab, var(--accent) 70%, var(--ink));

    --font: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
    --step--1: 0.875rem;
    --step-0: clamp(1.05rem, 1rem + 0.25vw, 1.2rem);
    --step-1: clamp(1.2rem, 1.1rem + 0.5vw, 1.45rem);
    --step-2: clamp(1.6rem, 1.4rem + 1vw, 2.2rem);
    --step-3: clamp(2.2rem, 1.7rem + 2.5vw, 3.6rem);

    --space-s: 0.75rem;
    --space-m: 1.5rem;
    --space-l: clamp(2.5rem, 2rem + 3vw, 4.5rem);
    --gutter: clamp(1rem, 0.5rem + 3vw, 2.5rem);
    --content: 72rem;
    --measure: 66ch;
    --pad: max(var(--gutter), (100% - var(--content)) / 2);

    /* Quick to answer, slow to settle: every hover and press uses it. */
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --quick: 160ms;
  }
  @media (prefers-color-scheme: dark) {
    :root {
      --accent: #35b56d;
      --accent-hover: #4cc98a;
      --on-accent: #161616;
      --sea: #74bcda;
      --fixed: #eaad55;
      --ink: #ececec;
      --muted: #a9a9a9;
      --paper: #141615;
      --stone: #1d201f;
    }
  }

  html {
    accent-color: var(--accent);
    font-family: var(--font);
    line-height: 1.55;
    color: var(--ink);
    background: var(--paper);
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    scrollbar-color: color-mix(in oklab, var(--ink) 25%, var(--paper)) transparent;
  }
  @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

  body {
    font-size: var(--step-0);
    min-block-size: 100dvh;
    display: grid;
    grid-template-rows: auto 1fr auto;
  }

  h1, h2, h3 { font-weight: 600; line-height: 1.15; text-wrap: balance; letter-spacing: -0.01em; }
  h1 { font-size: var(--step-3); letter-spacing: -0.02em; }
  h2 { font-size: var(--step-2); }
  h3 { font-size: var(--step-1); }
  p, li { max-inline-size: var(--measure); text-wrap: pretty; }

  a {
    color: var(--accent);
    text-underline-offset: 0.18em;
    text-decoration-thickness: from-font;
    text-decoration-color: color-mix(in oklab, currentColor 45%, transparent);
    transition: color var(--quick) var(--ease-out), text-decoration-color var(--quick) var(--ease-out);
    &:hover { color: var(--accent-hover); text-decoration-color: currentColor; }
  }
  :focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 2px; }
  ::selection { background: color-mix(in oklab, var(--accent) 22%, var(--paper)); color: var(--ink); }

  .sr-only { position: absolute; inline-size: 1px; block-size: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
}

@layer layout {
  .masthead, main > *, .colophon { padding-inline: var(--pad); }

  .masthead {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-s) var(--space-m);
    padding-block: var(--space-m);
  }
  .masthead nav {
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem var(--space-m);
    /* Four words on one line at a phone's width, not three and a straggler. */
    @media (width < 30rem) { inline-size: 100%; justify-content: space-between; gap: 0.25rem 0.75rem; }
  }
  .masthead nav a {
    color: var(--ink);
    text-decoration: none;
    padding-block: 0.4em;
    &:hover, &[aria-current] { color: var(--accent); text-decoration: underline; text-decoration-color: currentColor; }
  }
  .brand {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    font-weight: 700;
    font-size: var(--step-1);
    color: var(--ink);
    text-decoration: none;
    & img { inline-size: 2rem; block-size: 2rem; }
  }

  .colophon {
    display: grid;
    gap: 0.4rem;
    padding-block: var(--space-l);
    border-block-start: 1px solid var(--line);
    color: var(--muted);
    font-size: var(--step--1);
  }
}

@layer components {
  .hero {
    display: grid;
    gap: var(--space-m);
    padding-block: var(--space-l);
    & h1 { max-inline-size: 20ch; }
    &.narrow { padding-block-end: var(--space-m); }
  }
  .lede { font-size: var(--step-1); color: var(--muted); max-inline-size: 52ch; }
  .actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-m); }
  .button {
    display: inline-block;
    padding: 0.7em 1.3em;
    border-radius: 6px;
    background: var(--accent);
    color: var(--on-accent);
    font-weight: 600;
    text-decoration: none;
    box-shadow: 0 1px 2px color-mix(in oklab, #000 18%, transparent);
    transition: background-color var(--quick) var(--ease-out), transform var(--quick) var(--ease-out), box-shadow var(--quick) var(--ease-out);
    &:hover { background: var(--accent-hover); color: var(--on-accent); }
    &:active { transform: translateY(1px); box-shadow: none; }
  }

  /* A link further into the site: an arrow that leans the way it goes. */
  .onward {
    display: inline-flex;
    align-items: center;
    gap: 0.35em;
    &::after {
      content: "";
      inline-size: 0.8em;
      block-size: 0.8em;
      flex: none;
      background: currentColor;
      mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M2.5 8h10M8.5 3.5 13 8l-4.5 4.5'/%3E%3C/svg%3E") center / contain no-repeat;
      transition: translate var(--quick) var(--ease-out);
    }
    &:hover::after { translate: 0.2em 0; }
  }

  .band {
    display: grid;
    gap: var(--space-m);
    padding-block: var(--space-l);
    border-block-start: 1px solid var(--line);
    & > p { max-inline-size: var(--measure); }
  }
  .band:nth-of-type(even) { background: var(--stone); }

  .features {
    display: grid;
    gap: var(--space-m) var(--space-l);
    grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
    column-gap: var(--space-m);
    & article { display: grid; gap: 0.4rem; align-content: start; }
  }
  .split, .pair {
    display: grid;
    gap: var(--space-m) var(--space-l);
    grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
    align-items: start;
  }
  .pair article { display: grid; gap: var(--space-s); }
  .points {
    display: grid;
    gap: var(--space-m);
    list-style: none;
    & strong { display: block; }
  }
  .feature-wide p { font-size: var(--step-1); line-height: 1.5; max-inline-size: 60ch; }
  .feature-wide p + p { font-size: var(--step-0); }

  .changes {
    display: grid;
    gap: var(--space-s);
    list-style: none;
    & li { padding-inline-start: 1rem; border-inline-start: 3px solid var(--line); }
    & li { scroll-margin-block-start: var(--space-m); }
    /* Arriving from the feed at one change: it is lit, then settles back
       among the others once it has been found. */
    & li:target { animation: found 2.4s var(--ease-out) 0.3s both; }
  }
  @keyframes found {
    from { background: color-mix(in oklab, var(--accent) 16%, transparent); }
    to { background: transparent; }
  }
  @media (prefers-reduced-motion: reduce) {
    .changes li:target { animation: none; background: color-mix(in oklab, var(--accent) 10%, transparent); }
  }
  /* What kind of change, and who can see it: a word each, above the text. */
  .tags {
    display: flex;
    gap: 0.6rem;
    font-size: var(--step--1);
    font-weight: 600;
    & .kind { color: var(--muted); }
    & .kind.feature { color: var(--accent); }
    & .kind.improvement { color: var(--sea); }
    & .kind.fix { color: var(--fixed); }
    & .who { color: var(--muted); font-weight: 400; }
  }

  .log {
    display: grid;
    gap: var(--space-l);
    padding-block: var(--space-m) var(--space-l);
    & section { display: grid; gap: var(--space-s); scroll-margin-block-start: var(--space-m); }
    & h2 { font-size: var(--step-1); }
    & h2 time { color: var(--muted); }
  }
}

@layer components {
  /* A screenshot of the app: a picture of a page, framed so it reads as
     one against a page of the same colours. */
  .shot img {
    inline-size: 100%;
    block-size: auto;
    border: 1px solid var(--line);
    border-radius: 8px;
    box-shadow: 0 1px 2px color-mix(in oklab, #000 8%, transparent), 0 8px 24px color-mix(in oklab, #000 8%, transparent);
    background: var(--paper);
  }
  .shot.phone img { border-radius: 18px; }
  .hero .shot {
    margin-block-start: var(--space-m);
    /* The picture is a screen's height of a longer page; let its foot go
       soft so the crop reads as the page carrying on, not a cut. */
    mask-image: linear-gradient(to bottom, #000 78%, transparent);
    padding: 0 28px 28px;
    margin-inline: -28px;
  }

  /* A step of a tour: the words beside the picture from a laptop width,
     above it on a phone. */
  .tour {
    grid-template-columns: minmax(16rem, 1fr) minmax(0, 2fr);
    align-items: start;
    & .words { display: grid; gap: var(--space-s); position: sticky; inset-block-start: var(--space-m); }
    @media (width < 52rem) {
      grid-template-columns: 1fr;
      & .words { position: static; }
    }
  }
  /* Where a step stands among the six: the same rail the booking pages
     carry at their head, the steps behind done and this one filling in
     as it comes into view. */
  .tour { view-timeline: --step block; }
  .steps {
    display: flex;
    gap: 4px;
    inline-size: min(100%, 12rem);
    & [aria-hidden] {
      flex: 1;
      block-size: 3px;
      border-radius: 2px;
      background: var(--line);
    }
    & .done { background: var(--accent); }
    & .now { background: linear-gradient(var(--accent), var(--accent)) left / 100% 100% no-repeat, var(--line); }
  }
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .steps .now {
        animation: fill-in linear both;
        animation-timeline: --step;
        animation-range: entry 40% cover 35%;
      }
    }
  }
  @keyframes fill-in { from { background-size: 0 100%, auto; } }

  /* After the sixth, a tick: booked. It arrives as the last segment
     finishes filling, and is simply there where nothing moves. */
  .steps:has(.booked) { position: relative; }
  .steps .booked {
    /* Beside the rail rather than in it, so the sixth rail is as long
       as the five before it. */
    position: absolute;
    inset-inline-start: calc(100% + 0.3rem);
    inset-block-start: 50%;
    translate: 0 -50%;
    inline-size: 0.95rem;
    block-size: 0.95rem;
    background: var(--accent);
    mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%23000' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m3 8.5 3.2 3L13 4.5'/%3E%3C/svg%3E") center / contain no-repeat;
  }
  @supports (animation-timeline: view()) {
    @media (prefers-reduced-motion: no-preference) {
      .steps .booked {
        animation: tick linear both;
        animation-timeline: --step;
        animation-range: cover 30% cover 38%;
      }
    }
  }
  @keyframes tick {
    from { opacity: 0; scale: 0.4; clip-path: inset(0 100% 0 0); }
    60% { opacity: 1; }
    to { opacity: 1; scale: 1; clip-path: inset(0 0 0 0); }
  }

  /* The page that is not there, drawn as the staff pages draw a room:
     its beds in one strip, and nobody in any of them. */
  .vacant {
    display: inline-flex;
    align-items: center;
    gap: var(--space-m);
    justify-self: start;
    margin-block-start: var(--space-s);
    padding: 0.75rem 1rem;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--stone);
    font-size: var(--step--1);
    & .beds { display: flex; border: 1px solid color-mix(in oklab, var(--ink) 30%, var(--paper)); border-radius: 5px; }
    & .beds span { inline-size: 28px; block-size: 22px; background: var(--paper); }
    & .beds span + span { border-inline-start: 1px solid color-mix(in oklab, var(--ink) 30%, var(--paper)); }
    & .beds span:first-child { border-radius: 4px 0 0 4px; }
    & .beds span:last-child { border-radius: 0 4px 4px 0; }
  }
  .pair-shots {
    display: grid;
    grid-template-columns: minmax(0, 3fr) minmax(0, 1fr);
    gap: var(--space-m);
    align-items: start;
  }
}
