/* ===================================================================== *
 * law.css, the "The law, in three lines" band.
 *
 * One section from the front page redesign, built from the Figma frame
 * "Panel / The law, in three lines". Loaded after app.css and only by
 * index.html.
 *
 * Three cards, all answering the same question: does this land on you.
 * The label names the case, the serif line is the answer, the pill is the
 * engine's own level for that case. The pill is the real `.pill` component
 * out of app.css with a real `data-level`, not a lookalike, so the band
 * cannot drift away from what the checker returns underneath it.
 *
 * EVERY class here is namespaced `law__`, for the reason know.css gives at
 * length: the app owns the short names. The one borrowed class is `.pill`,
 * and that is borrowed deliberately.
 *
 * It slots into the existing `components` layer rather than sitting
 * unlayered on top. Unlayered rules beat every layer, which would silently
 * outrank the whole stylesheet.
 * ===================================================================== */

@layer tokens {
  :root {
    /* blue70 off the base scale. --select-fg is the same value but means
       "the text of the thing you picked", so a band background borrowing it
       would be borrowing a name it has no business borrowing. Its own token,
       the same argument know.css makes for --panel-blue. */
    --law-band: #004285;

    /* The band is dark in both schemes, so the type on it is light in both.
       It cannot use --text, which is navy in light and would vanish. */
    --law-ink: #ffffff;
    --law-ink-muted: rgb(255 255 255 / 0.72);

    /* The hairline under the answer, inside the card. Tinted from the card's
       own ink rather than --border: --border is warm grey off the page
       background and reads as a smudge on white at this weight. */
    --law-rule: rgb(0 52 107 / 0.14);

    /* The citation link. Blue10 ground, accent text, straight off the frame. */
    --law-cite-bg: #cce9ff;
    --law-cite-ink: #0040ff;

    /* White on blue70 is 8.6:1, so the card's own edge is the contrast and
       there is nothing for a border to add. Declared anyway so the rule below
       never has to branch on scheme. */
    --law-card-edge: transparent;

    /* The arrival. Kept together because the feel of it is a judgement rather
       than a fact, and should be adjustable without reading the rules below.

       The rise is small on purpose. These are cards on a coloured band, not
       slides: anything past about 20px and they read as flying in, which is
       the wrong register for a page about what the law requires of you. */
    --law-rise: 16px;
    /* Shorter than the stagger is wide, on purpose. A card that runs longer
       than the gap to the next one is still moving when its neighbour starts,
       and since each chip waits on its own card, the three chips end up
       landing on top of each other at the end of the run. That reads as the
       cards arriving and then the chips arriving, which is the wrong pairing.
       Keep --law-in low enough that a card finishes near its neighbour's
       start and the three card-and-chip pairs stay legible as pairs. */
    --law-in: 700ms;
    --law-stagger: 250ms;

    /* The chip lands after its own card has finished, not with it. It is the
       verdict, and a verdict arriving at the same moment as the case it
       answers reads as one event rather than two. Quick, because it is a
       small object and the card has already done the slow part.

       0.8 rather than 0: a chip growing from nothing draws more attention
       than the sentence it is labelling. */
    --law-chip-in: 420ms;
    --law-chip-from: 0.8;
  }

  @media (prefers-color-scheme: dark) {
    :root {
      /* Read one step back up the same scale, to blue80. know.css takes its
         band down to blue90, and two sections sitting at the same value would
         run together into one long block of navy. This stays the lighter of
         the two, which is also the relationship they have in light. */
      --law-band: #00346b;

      /* White at 14 per cent, because the card is near-black here and a navy
         tint has nothing to sit against. */
      --law-rule: rgb(255 255 255 / 0.14);

      /* Blue10 on blue80 is two neighbours and the pill disappears. A white
         tint reads on any dark ground, and blue20 carries the link colour
         without going bright. */
      --law-cite-bg: rgb(255 255 255 / 0.10);
      --law-cite-ink: #85ccff;

      /* The near-black card sits 1.5:1 off the navy band, which is not an edge.
         Same problem know.css hits with its screens, same answer: a white
         hairline, because --border at #26262a measures nothing against navy. */
      --law-card-edge: rgb(255 255 255 / 0.16);
    }
  }
}

@layer components {

  /* -- the band ------------------------------------------------------- *
     Colour runs the full width of the window, words stay inside the 1440
     column. One element cannot do both, so the band paints and the shell
     inside it measures. Same structure as .topbar, .footer and .know. */
  .law {
    background: var(--law-band);
    padding-block: var(--space-9) var(--space-7);
  }

  @media (max-width: 48rem) {
    .law { padding-block: var(--space-7) var(--space-6); }
  }

  /* Heading left, citation right, sitting on the same baseline. The citation
     aligns to the bottom of the block rather than the top: against a two line
     heading plus a subheading, top alignment left it floating opposite the
     display type with nothing to relate to. */
  .law__head {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: var(--space-5);
    margin-bottom: var(--space-7);
  }

  /* The same ramp as .know__title, deliberately. Two section headings on one
     page that step at different widths read as two different pages. */
  .law__title {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 600;
    line-height: 1.06;
    color: var(--law-ink);
  }

  .law__sub {
    margin-top: var(--space-2);
    font-size: var(--text-lg);
    line-height: 1.55;
    color: var(--law-ink-muted);
    text-wrap: pretty;
  }

  @media (min-width: 48rem) {
    .law__title { font-size: var(--text-3xl); }
  }

  @media (min-width: 64rem) {
    .law__title { font-size: 3.25rem; }  /* 52, per the frame */
  }

  .law__cite {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-3) var(--space-5);
    border-radius: var(--radius-full);
    background: var(--law-cite-bg);
    color: var(--law-cite-ink);
    font-size: var(--text-base);
    text-decoration: none;
  }

  .law__cite:hover { text-decoration: underline; text-underline-offset: 3px; }

  /* The focus ring is the page's, but it needs a gap: the pill sits on a dark
     band and a ring drawn tight to a light pill is hard to separate from the
     pill's own edge. */
  .law__cite:focus-visible {
    outline: 2px solid var(--law-ink);
    outline-offset: 3px;
  }

  .law__cite .icon {
    width: 0.9375rem;
    height: 0.9375rem;
  }

  /* -- the cards ------------------------------------------------------ *
     One column, then three. Never two: three items across two columns leaves
     a single card on its own row, which reads as a card that failed to load
     rather than as the third of three. */
  .law__cards {
    display: grid;
    grid-template-columns: 1fr;
    gap: var(--space-5);
    margin: 0;
    padding: 0;
    list-style: none;
  }

  @media (min-width: 64rem) {
    .law__cards { grid-template-columns: repeat(3, 1fr); }
  }

  /* -- the carousel --------------------------------------------------- *
     Stacked, the three cards run to most of three screens on a phone, for a
     band whose whole claim is that it can be taken in at a glance. Sideways
     instead: the first card whole, a third of the second showing past it so
     there is something visibly to reach for, and snap points so it comes to
     rest on a card rather than between two.

     The 75% and the gutter-width gap are load bearing together. Cancelling
     the shell gutter and re-adding it as padding makes the visible run one
     content box plus one gutter, so a card at 75% of the content box leaves
     a quarter of that box showing past the gap, and a quarter of the box is
     a third of a card. It holds at every phone width. Change either number
     on its own and the third stops being a third. */
  @media (max-width: 47.999rem) {
    .law__cards {
      /* The single explicit column has to go first. Left in place it would
         take item one at 1fr and only items two and three at the card width. */
      grid-template-columns: none;
      grid-auto-flow: column;
      grid-auto-columns: 75%;
      gap: var(--shell-pad);

      /* Out to the screen edges, then back in by the same amount as padding,
         so a card can leave the side of the screen while the first still
         lines up with the heading above it. .shell publishes --shell-pad for
         exactly this kind of break-out. */
      margin-inline: calc(var(--shell-pad) * -1);
      padding-inline: var(--shell-pad);

      overflow-x: auto;
      scroll-snap-type: x mandatory;
      scroll-padding-inline: var(--shell-pad);
      /* A sideways flick at the end of the track should stop, not hand the
         gesture to the browser and trigger a back navigation. */
      overscroll-behavior-x: contain;

      /* overflow-x: auto makes the other axis auto too, and the cards arrive
         16px low, which would give the track its own vertical scrollbar for
         as long as the animation runs. Room for the rise, taken straight back
         off the outside so nothing below it moves. */
      padding-block-end: var(--law-rise);
      margin-block-end: calc(var(--law-rise) * -1);
    }

    .law__card { scroll-snap-align: start; }
  }

  /* Grid stretches the row, so the cards match heights without anything here
     asking them to. The flex column is for the inside: it keeps the gaps even
     when one card's copy runs a line longer than its neighbours'. */
  .law__card {
    display: flex;
    flex-direction: column;
    gap: var(--space-4);
    padding: var(--space-6);
    border: 1px solid var(--law-card-edge);
    border-radius: var(--radius-xl);
    background: var(--surface);
  }

  /* Case on the left, level on the right. The two are different kinds of
     thing, which is why they sit at opposite ends rather than next to each
     other: one names the situation, one is the verdict. */
  .law__meta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-3);
  }

  /* The frame sets this at 11. The scale stops at 12 and one section is not
     a reason to extend it downwards, so it takes the 12 and the tracking does
     the rest of the work. */
  .law__case {
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--text-subtle);
  }

  .law__answer {
    font-family: var(--font-display);
    font-size: var(--text-3xl);
    font-weight: 600;
    line-height: 1.1;
    color: var(--text);
  }

  /* The rule belongs to the block below it, not to the answer above it. Drawn
     as this block's top border rather than as its own element, so there is
     nothing in the markup pretending to be content. */
  .law__text {
    border-top: 1px solid var(--law-rule);
    padding-top: var(--space-4);
  }

  /* An h3, so the base layer has already put it in the display serif with the
     tracking that serif wants. Both get taken back: the serif is the answer's
     job on this card, and a second serif directly under it flattens the step
     between them. Inter, bold, and the negative tracking released, which was
     cut for STIX at display sizes and only tightens Inter at 16. */
  .law__point {
    font-family: var(--font-sans);
    font-size: var(--text-base);
    font-weight: 700;
    letter-spacing: normal;
    line-height: 1.4;
    color: var(--text);
  }

  .law__body {
    margin-top: var(--space-2);
    font-size: var(--text-base);
    line-height: 1.625;
    color: var(--text-muted);
    text-wrap: pretty;
  }

  /* -- the arrival ---------------------------------------------------- *
     Three cards up in sequence as the band comes into view, then the note.

     The hidden state hangs off [data-observed], which only law.js sets. No
     JavaScript, a thrown error, a script that never runs: the attribute never
     lands and the cards are simply there. The one thing this must never do is
     leave the statute invisible because a nicety failed.

     All of it sits inside no-preference. Anyone who has asked for less
     movement gets the cards with no fade and no travel, which is the same
     bargain know.css makes for its screens.

     An animation rather than a transition, which was the first attempt and
     the wrong tool. A transition has to already be on the element before the
     values change, so declaring it alongside the hidden state left the cards
     transitioning into hiding on load: the wrong half of the move, animated.
     A keyframe only ever runs forwards, and `both` holds the opening frame
     through the delay so a staggered card does not flash before its turn. */
  @media (prefers-reduced-motion: no-preference) {
    .law[data-observed] .law__card,
    .law[data-observed] .law__note,
    .law[data-observed] .law__card .pill {
      opacity: 0;
    }

    .law[data-in] .law__card,
    .law[data-in] .law__note {
      animation: law-rise var(--law-in) var(--ease) var(--law-delay, 0ms) both;
    }

    /* Scoped to .law on purpose. `.pill` is the app's own component and the
       findings table is full of them; a bare `.pill` rule here would have the
       result animating every time it re-renders.

       The delay is its card's delay plus the card's full duration, so each
       chip is waiting on its own card and not on a clock. Change the stagger
       and the chips follow without anything else being touched. */
    .law[data-in] .law__card .pill {
      animation: law-pop var(--law-chip-in) var(--ease)
                 calc(var(--law-delay, 0ms) + var(--law-in)) both;
    }

    /* Counted off the cards rather than set from JavaScript, so the sequence
       is one place to change and the script stays a switch. */
    .law[data-in] .law__card:nth-child(2) { --law-delay: var(--law-stagger); }
    .law[data-in] .law__card:nth-child(3) { --law-delay: calc(var(--law-stagger) * 2); }
    .law[data-in] .law__note { --law-delay: calc(var(--law-stagger) * 3); }
  }

  @keyframes law-rise {
    from { opacity: 0; transform: translateY(var(--law-rise)); }
    to   { opacity: 1; transform: none; }
  }

  @keyframes law-pop {
    from { opacity: 0; transform: scale(var(--law-chip-from)); }
    to   { opacity: 1; transform: none; }
  }

  /* The provider's duty. Below the cards and quieter than them, because it is
     the one thing on this band that is not about the reader, and because the
     mistake it exists to head off is reading it as an all clear. Held to a
     reading measure so it cannot run the full 1440 as one line. */
  .law__note {
    max-width: 44rem;
    margin-top: var(--space-5);
    font-size: var(--text-base);
    line-height: 1.6;
    color: var(--law-ink-muted);
    text-wrap: pretty;
  }
}
