/* ===================================================================== *
 * know.css, the "Know before you post" panel.
 *
 * One section from the front page redesign, built from the Figma frame
 * "Know before you post / three steps". Loaded after app.css and only by
 * index.html.
 *
 * Currently three static panels, one per step. When the panel is made
 * interactive, two of them go and the screens become tab panels; the
 * markup is already grouped so that swap touches the JS and not this file.
 *
 * EVERY class here is namespaced `know__`. The first draft used plain
 * names, and `.findings` collided with the real findings table in app.css,
 * which handed the marketing rows a white card background, a border and a
 * radius nobody asked for. The app owns the short names. This block does
 * not get to borrow them.
 *
 * 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 {
    /* blue10 off the supplied base scale. --select-bg is the same value but
       means "you picked this", so a panel background borrows a name it has
       no business borrowing. This is its own token. */
    --panel-blue: #cce9ff;
    /* The lit step. A tint of blue30 over the panel rather than a new hue. */
    --panel-lit: rgb(87 185 255 / 0.38);
    /* The unlit step marker. Registered in data/palette.json as Pale signal. */
    --panel-dot: #eaf1ff;
    /* --radius-xl and --space-9 used to be declared here. law.css became the
       second section to want both, which is the condition this file set for
       promoting them, so they now live on the scales in app.css. */
    /* The screen edge. Light leans on the shadow; dark cannot, so it swaps
       to a hairline. Declared here so the rule below never branches. */
    --panel-edge: transparent;

    /* How a screen arrives and leaves. Four numbers, kept together, because
       the feel of this is a judgement rather than a fact and should be
       adjustable without reading any of the rules that use it.

       The angle is the one to argue about. 30deg is a lot for a panel this
       size: the corners swing a long way and it reads as thrown rather than
       placed. Somewhere around 8deg to 12deg gives the same fluidity without
       the drama. It is 30 because that is what was asked for, and it is one
       number to change. */
    /* Negative, so the tilt is anticlockwise: the right edge lifts and the
       left drops. Read off the reference, where the incoming screen's
       top-right corner sits higher than its top-left. Clockwise was the
       first attempt and it leans the wrong way. */
    --screen-angle: -30deg;

    /* The narrow-screen arrival, with its own angle as well as its own
       distances. It reads well as it is and is deliberately not following the
       desktop numbers: it is a keyframe rather than a transition, because
       display:none cannot be transitioned across, so it could not share them
       even if it wanted to. */
    --screen-drift: 32px;
    --screen-rise: 44px;
    --screen-tilt: 30deg;

    /* Wide screens get a long arrival and a short departure, deliberately
       lopsided. A screen swings up from below and to the LEFT while it
       untwists, which is what makes the rotation read as a turn rather than
       a wobble. Going out it only lifts a little, tipping back the same way
       it arrived, so the exit is the arrival's echo rather than its reverse.

       Left, not right. The reference puts the waiting screen well to the
       left of where it lands, and coming from the left means it travels
       across the panel rather than in from its own edge. */
    --screen-enter-x: -170px;
    --screen-enter-y: 170px;
    --screen-exit-x: -46px;
    --screen-exit-y: 44px;

    /* Arriving covers roughly four times the distance of leaving, so it is
       given longer. Matching them would make the entrance feel hurried. */
    --screen-in: 520ms;
    --screen-out: 360ms;

    /* Three layers, not one. A contact shadow holding the bottom edge, a
       mid layer for the body, a wide soft one for the ambient light. One
       layer reads as a sticker; three read as a panel lifted off the page.
       Tinted navy rather than grey, for the same reason the neutrals are
       warmed: a grey shadow on this page looks like a different family. */
    --panel-lift:
      0 2px 6px rgb(0 52 107 / 0.10),
      0 10px 22px -6px rgb(0 52 107 / 0.14),
      0 26px 54px -10px rgb(0 52 107 / 0.16);
  }

  @media (prefers-color-scheme: dark) {
    :root {
      /* Read from the other end of the same scale: blue90 ground, and the
         lit step lightens rather than deepens, as the accent does. */
      --panel-blue: #001938;
      --panel-lit: rgb(87 185 255 / 0.18);
      --panel-dot: rgb(255 255 255 / 0.10);
      /* Two dark surfaces sit ~1.1:1 apart, so a shadow cannot hold the
         screen's edge here. A hairline does the job a shadow does in light.
         Not --border: at #26262a against this navy it measured 1.16:1, which
         is no edge at all. A white tint reads on any dark ground. */
      --panel-edge: rgb(255 255 255 / 0.16);
      --panel-lift:
        0 2px 6px rgb(0 0 0 / 0.40),
        0 10px 22px -6px rgb(0 0 0 / 0.45),
        0 26px 54px -10px rgb(0 0 0 / 0.50);
    }
  }
}

@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 and .footer. */
  /* Deeper above than below, on purpose. The band has to clear the picker it
     sits under, and the picker's own rows carry visual weight right to their
     edge, so an even inset read as cramped at the top and loose at the
     bottom. 96 over 48. */
  .know {
    background: var(--panel-blue);
    padding-block: var(--space-9) var(--space-7);
  }

  /* Both step down together on a phone, where 96 is most of the screen before
     anything has been said. */
  @media (max-width: 48rem) {
    .know { padding-block: var(--space-7) var(--space-6); }
  }

  /* Centred in the band and centred on itself. The measure stays capped:
     centred lines are harder to come back to at the start of the next one,
     so a long line hurts here more than it would ranged left. */
  .know__head {
    max-width: 45rem;
    margin-inline: auto;
    text-align: center;
  }

  /* Steps down with the page. The hero drops to 28 on a phone, and a section
     heading below it must never end up larger than the thing it sits under. */
  .know__title {
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 600;
    line-height: 1.06;
    color: var(--text);
  }

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

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

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

  /* Centred, as in the frame. Safe again now every description is on screen:
     both columns have a height that does not change, so there is nothing for
     centring to re-centre. */
  .know__body {
    margin-top: var(--space-7);
    display: grid;
    gap: var(--space-6);
    align-items: center;
  }

  @media (min-width: 64rem) {
    .know__body {
      grid-template-columns: 1fr 1fr;
      gap: var(--space-8) calc(var(--space-8) - 8px);
    }
  }

  /* -- the steps ------------------------------------------------------ */
  .know__steps {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
    list-style: none;
    padding: 0;
  }

  /* The whole card is the control, so the button carries the padding and the
     radius rather than sitting inside something that does. */
  .know__step {
    display: flex;
    gap: var(--space-4);
    align-items: flex-start;
    width: 100%;
    padding: 22px var(--space-5);
    border: 0;
    border-radius: 20px;
    background: transparent;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
    /* Colour only. Nothing moves when a step lights up, so the list does
       not reflow as you read down it. */
    transition: background 0.22s var(--ease);
  }

  .know__step[aria-selected="true"] { background: var(--panel-lit); }

  .know__step:hover { background: color-mix(in oklab, var(--panel-lit) 45%, transparent); }

  .know__step:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
  }

  .know__step-text {
    display: block;
    min-width: 0;
  }

  /* Every description stays on screen, on every step.

     Showing only the selected one meant the column changed height as you
     moved, because the three are not the same number of lines, and the whole
     list shifted under the pointer. Reading all three at once also means you
     can see what the checker asks before you click anything.

     So the only thing that changes on click is the screen on the right. */

  .know__dot {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: var(--radius-full);
    background: var(--panel-dot);
    color: var(--accent);
    font-size: 0.875rem;
    font-weight: 600;
  }

  .know__step[aria-selected="true"] .know__dot {
    background: var(--accent);
    color: var(--accent-text);
  }

  .know__step-title {
    /* Spans, not a heading and a paragraph: a tab is a label for a panel,
       not an entry in the document outline, and a heading inside a button is
       invalid. So the block behaviour they used to get for free is set here. */
    display: block;
    /* Inter, not the display face. The serif is for section headings and
       for the app's own h1/h2/h3; a title inside a card is neither. */
    font-family: var(--font-sans);
    font-size: var(--text-xl);
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.27;
    color: var(--text);
  }

  .know__step-body {
    display: block;
    margin-top: var(--space-1);
    font-size: var(--text-base);
    line-height: 1.56;
    color: var(--text-muted);
    text-wrap: pretty;
  }

  /* -- the preview screens --------------------------------------------- *
     A picture of the app, not the app. Nothing inside is focusable; the
     panel itself takes focus, because its content cannot.

     Two things have to be true at once here, and they pull against each
     other:

       the screen itself resizes, so it is only as tall as the step it is
       showing, as in the Figma file;

       the panel does not, so the steps beside it hold still and the page
       below it never shifts.

     So all three share one grid cell, which holds the reserved height at the
     tallest of them, and the visible one aligns to the top of that cell
     rather than stretching to fill it. The cell is the fixed panel; the
     screen inside it is free to be its own size.

     No hard-coded height: the tallest screen sets it, so this survives the
     copy changing.

     Hidden screens use visibility rather than display. display would
     collapse the reserved height and put the jumping straight back. */
  .know__screens {
    min-width: 0;
    /* The cursor is positioned against this box, so it can travel between
       screens without belonging to any one of them. */
    position: relative;
  }

  /* -- the walkthrough cursor ------------------------------------------ *
     A drawn pointer, not a real one. Two elements because it needs two
     transforms at once: the outer one travels, the inner one presses.
     Stacking them on a single transform would make the click cancel the
     journey.

     It is decoration for a demonstration, so it is hidden from assistive
     technology and cannot be pointed at. */
  .know__cursor {
    position: absolute;
    top: 0;
    left: 0;
    width: 40px;
    height: 40px;
    z-index: 2;
    opacity: 0;
    pointer-events: none;
    /* Duration is a variable because the journey has two speeds: coming in
       from the corner and leaving again are slower than moving between two
       things already on screen. know.js sets it per move.

       The fade is 70% of the travel, so the pointer arrives out of the corner
       rather than appearing parked and then setting off. */
    --cursor-travel: 560ms;
    transition: transform var(--cursor-travel) var(--ease),
                opacity calc(var(--cursor-travel) * 0.7) var(--ease);
  }

  .know__cursor[data-in] { opacity: 1; }

  .know__cursor span {
    display: block;
    width: 100%;
    height: 100%;
    transition: transform 0.12s var(--ease);
  }

  .know__cursor[data-press] span { transform: scale(0.8); }

  .know__cursor svg {
    display: block;
    width: 100%;
    height: 100%;
    /* A white keyline, so the pointer stays legible over the amber verdict
       band and the blue Copy button alike. */
    filter: drop-shadow(0 1px 2px rgb(0 52 107 / 0.35));
  }

  /* Anyone who has asked for less movement gets the panel with no pointer
     and no journey. The screens still change when they pick a step. */
  @media (prefers-reduced-motion: reduce) {
    .know__cursor { display: none; }
  }

  /* Narrow first: the screen simply sizes to its content and the ones behind
     it are not in the layout at all. There is no column beside it to stay
     level with here, and reserving the tallest would spend 270px of phone on
     nothing. */
  .know__screen {
    display: none;
    background: var(--bg);
    border: 1px solid var(--panel-edge);
    border-radius: var(--radius-xl);
    box-shadow: var(--panel-lift);
    overflow: clip;
  }

  .know__screen[data-on] { display: block; }

  /* Two columns, and now the reservation earns its keep. */
  @media (min-width: 64rem) {
    .know__screens { display: grid; }

    .know__screen {
      display: block;
      grid-area: 1 / 1;
      /* Centred in the reserved cell, so a short screen sits level with the
         middle of the steps beside it rather than riding high against them.
         It still grows and shrinks; it does so from the middle, and nothing
         outside the cell moves either way. */
      align-self: center;
      visibility: hidden;
      opacity: 0;
      /* Waiting well below and to the right, tipped over. This is where a
         screen climbs up from. */
      transform: translate(var(--screen-enter-x), var(--screen-enter-y))
                 rotate(var(--screen-angle));
    }

    .know__screen[data-on] {
      visibility: visible;
      opacity: 1;
      transform: none;
    }

    /* Leaving is not the reverse of arriving, so it needs its own state. A
       screen rises and tips the other way as it goes, rather than reversing
       back down to the corner it came from. Set by know.js on the screen being
       replaced, and cleared once it has gone. */
    .know__screen[data-leaving] {
      opacity: 0;
      transform: translate(var(--screen-exit-x), calc(var(--screen-exit-y) * -1))
                 rotate(var(--screen-angle));
    }
  }

  /* Below the two-column layout the screens are display:none, which no
     transition can cross. An arrival animation still can, so narrow screens
     get the entrance and skip the exit rather than losing both. */
  @keyframes know-screen-in {
    from {
      opacity: 0;
      transform: translate(var(--screen-drift), var(--screen-rise))
                 rotate(var(--screen-tilt));
    }
    to { opacity: 1; transform: none; }
  }

  @media (max-width: 63.999rem) and (prefers-reduced-motion: no-preference) {
    .know__screen[data-on] {
      animation: know-screen-in var(--screen-in) var(--ease) both;
    }
  }

  /* The entrance above drifts the screen 32px sideways and tips it 30deg, and
     a rotated box is wider than the box it started as. Both are laid out in
     the page rather than painted over it, so on a phone the panel handed the
     whole document about 80px of sideways scroll: the page could be dragged
     off its own gutter, and the drawn cursor parked out there too. Neither
     was ever meant to be seen past the edge of the panel.

     overflow-x: clip, not hidden. `hidden` on one axis forces the other to
     become a scroll container, and this box has to keep growing downwards as
     the screens change height. `clip` leaves the vertical axis alone.

     The clip margin is for the screen's own shadow, which is real and should
     not be shaved off at the sides. 12px sits well inside the 24px shell
     gutter, so it can never reach the edge of the viewport.

     Narrow only. Above this the screens fly in and out across the panel on
     purpose, and clipping would have them vanish at its edge instead. */
  @media (max-width: 63.999rem) {
    .know__screens {
      overflow-x: clip;
      overflow-clip-margin: 12px;
    }
  }

  .know__screen:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 3px;
  }

  /* Arriving and leaving are different lengths, so the screen coming in is
     never waiting on the one going out.
     All of it is a nicety, not the mechanism. Anyone who has asked for less
     movement gets the swap with no fade, no travel and no tilt. */
  @media (prefers-reduced-motion: no-preference) {
    .know__screen {
      transition: opacity var(--screen-out) var(--ease),
                  transform var(--screen-out) var(--ease),
                  visibility var(--screen-out) var(--ease);
    }

    .know__screen[data-on] {
      transition: opacity var(--screen-in) var(--ease),
                  transform var(--screen-in) var(--ease),
                  visibility var(--screen-in) var(--ease);
    }
  }

  .know__screen--form { padding: var(--space-6); }

  .know__label {
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.09em;
    color: var(--text-subtle);
  }

  .know__question {
    margin-top: 14px;
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 400;
    line-height: 1.18;
    color: var(--text);
  }

  .know__group {
    margin-top: 14px;
    font-family: var(--font-display);
    font-size: 1.125rem;
    font-weight: 600;
    line-height: 1.33;
    color: var(--text);
  }

  .know__options {
    margin-top: 10px;
    display: grid;
    gap: 10px;
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  @media (max-width: 30rem) {
    .know__options { grid-template-columns: minmax(0, 1fr); }
  }

  .know__opt {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: 12px 15px;
    border: 1px solid var(--border);
    border-radius: var(--radius);
    background: var(--surface);
    font-size: 0.875rem;
    line-height: 1.43;
    color: var(--text-muted);
  }

  .know__opt[data-on] {
    background: var(--select-bg);
    border-color: var(--select-border);
    color: var(--select-fg);
    font-weight: 500;
  }

  /* The walkthrough cannot use :hover, because the pointer doing the work is
     a drawn one. Same values as .option:hover in app.css, so the demo shows
     what the app does rather than an impression of it. */
  .know__opt[data-hover] {
    background: color-mix(in oklab, var(--select-bg) 45%, var(--surface));
    border-color: var(--select-border);
  }

  /* The same line as .option__icon in app.css, deliberately. The real picker
     already colours these, from a `--brand` value set per content type in
     questions.json, so the mark is set inline in the markup and this only
     reads it. One source of truth: change the colour in questions.json and
     the picker and this preview move together.

     A content type with no real brand behind it, a blog article, has no
     --brand and falls back to the subtle ink, exactly as the app does. */
  .know__opt .icon {
    flex: none;
    color: var(--brand, var(--text-subtle));
  }

  /* Scoped to match `.know__opt .icon` above, which would otherwise win on
     specificity and paint the tick the same subtle ink as an unbranded mark.
     The tick is a selection mark, not a logo.

     It stays in the markup and hides, rather than being added and removed.
     The walkthrough only has to toggle one attribute, and the row does not
     change width at the moment it is chosen. */
  .know__opt .know__tick {
    display: none;
    flex: none;
    margin-left: auto;
    color: var(--select-mark);
  }

  .know__opt[data-on] .know__tick { display: block; }

  /* -- the answer screen ----------------------------------------------- */
  .know__verdict {
    background: var(--amber-bg);
    border-bottom: 1px solid var(--amber-border);
    color: var(--amber-fg);
    padding: 28px var(--space-6);
  }

  .know__eyebrow {
    font-size: var(--text-xs);
    font-weight: 600;
    letter-spacing: 0.08em;
  }

  .know__headline {
    margin-top: var(--space-2);
    font-family: var(--font-display);
    font-size: var(--text-2xl);
    font-weight: 600;
    line-height: 1.18;
    color: var(--amber-fg);
  }

  .know__act { padding: 28px var(--space-6); }

  .know__act-title {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    font-weight: 600;
    color: var(--text);
  }

  .know__copyable {
    margin-top: 14px;
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3) var(--space-3) var(--space-3) var(--space-5);
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--surface);
  }

  .know__copyable p {
    flex: 1 1 auto;
    font-size: var(--text-base);
    line-height: 1.5;
    color: var(--text);
  }

  /* -- the two copy confirmations -------------------------------------- *
     One rule for both: green border, green text, and a fill that separates
     the control from whatever it is sitting on. The button inside the row
     takes the surface, because the row underneath it has already gone green
     and a green button on a green field disappears. Mirrors app.css. */
  .know__copyable[data-hover] {
    background: color-mix(in oklab, var(--accent) 6%, var(--surface));
  }

  .know__copyable[data-hover] .know__btn { background: var(--accent-hover); }

  .know__copyable[data-copied] {
    background: var(--green-bg);
    border-color: var(--green-border);
  }

  .know__copyable[data-copied] .know__btn {
    background: var(--surface);
    border-color: var(--green-border);
    color: var(--green-fg);
  }

  .know__btn--ghost[data-hover] { background: var(--bg-sunken); }

  .know__btn--ghost[data-copied] {
    background: var(--green-bg);
    border-color: var(--green-border);
    color: var(--green-fg);
  }

  /* Pictures of buttons, not buttons. Rendered as spans so nothing here
     can be tabbed to or pressed, which is the honest thing for a control
     that does not do anything yet. */
  .know__btn {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-4);
    /* Transparent rather than none, so the confirmation can colour the border
       without the button changing size when it arrives. */
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    background: var(--accent);
    color: var(--accent-text);
    font-size: var(--text-base);
    font-weight: 500;
    white-space: nowrap;
  }

  .know__btn--ghost {
    margin-top: 14px;
    padding: 11px var(--space-5);
    border-color: var(--border-strong);
    background: none;
    color: var(--text);
  }

  /* Everything the walkthrough touches settles at the same rate, so a hover
     and the state it leads to feel like one movement rather than several. */
  @media (prefers-reduced-motion: no-preference) {
    .know__opt,
    .know__copyable,
    .know__btn {
      transition: background-color 0.18s var(--ease),
                  border-color 0.18s var(--ease),
                  color 0.18s var(--ease);
    }
  }

  .know__note {
    margin-top: var(--space-3);
    font-size: 0.8125rem;
    line-height: 1.54;
    color: var(--text-subtle);
  }

  .know__hr {
    margin-top: 14px;
    border: 0;
    border-top: 1px solid var(--border);
  }

  /* -- the ruling rows -------------------------------------------------- *
     Where the tags actually live in the product: the weight column of the
     findings table. Named `know__ruling` rather than `findings`, which the
     app already owns. */
  .know__ruling {
    margin-top: 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
    list-style: none;
    padding: 0;
  }

  .know__ruling li {
    display: flex;
    align-items: center;
    gap: var(--space-4);
  }

  .know__ruling p {
    font-size: 0.875rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    line-height: 1.43;
    color: var(--text);
  }

  .know__tag {
    flex: none;
    width: 7.375rem;              /* one column, so the findings line up */
    font-size: 0;                 /* collapses the inline-block gap */
  }

  .know__tag span {
    display: inline-block;
    padding: 3px var(--space-2);
    border-radius: var(--radius-xs);
    font-size: var(--text-xs);
    font-weight: 500;
    line-height: 1.6;
  }

  .know__tag--recommended span { background: var(--accent-lilac); color: #000; }
  .know__tag--context span { background: var(--accent-blue); color: #fff; }

  @media (max-width: 30rem) {
    .know__ruling li { flex-direction: column; align-items: flex-start; gap: var(--space-2); }
    .know__tag { width: auto; }
  }

  /* The panel belongs to the landing screen only. Once someone has started
     answering, they have already decided to use the tool, and a pitch for it
     sitting under the questions is just something in the way.

     Two signals, because one does not cover it. app.js hides the progress row
     on step one AND on the answer (`step === 1 || step === 4`), so the
     progress row alone would let the panel reappear under the verdict.
       progress showing  -> steps two and three
       result showing    -> the answer
     Landing is the only state where neither is true. */
  body:has(#progress:not([hidden])) .know,
  body:has(#result:not([hidden])) .know {
    display: none;
  }
}
