@layer base {
  *, *::before, *::after { box-sizing: border-box; }

  /* The scrollbar is part of the layout, so it is always part of the layout.

     Everything in this product is a column centred in the viewport, and a
     classic scrollbar is taken out of that viewport when it appears. So a page
     long enough to scroll was 15px narrower than one that is not, and the
     column moved 7px left as you went from Today to Members — every centred
     thing on the page shifting together, which is why it reads as "these two
     screens are very slightly different widths" rather than as a scrollbar.

     `stable` reserves the gutter whether or not there is anything to scroll.
     Not `both-edges`: that keeps the column mathematically centred and spends
     15px of the left margin to do it, and the asymmetry is smaller than the
     shift was. */
  html { scrollbar-gutter: stable; }

  body {
    margin: 0;
    background: var(--canvas);
    color: var(--ink);
    font-family: var(--font-sans);
    font-size: var(--text-base);
    line-height: var(--leading-body);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
  }

  h1, h2, h3 {
    margin: 0;
    line-height: var(--leading-tight);
    font-weight: var(--weight-heavy);
    letter-spacing: var(--tracking-tight);
    text-wrap: balance;
  }

  h1 { font-size: var(--text-xl); }
  h2 { font-size: var(--text-lg); }
  h3 { font-size: var(--text-md); letter-spacing: var(--tracking-normal); font-weight: var(--weight-bold); }

  p { margin: 0; max-width: var(--measure); }

  /* A form control does not inherit its family, and the UA sheet gives it one.
     In Chrome that is 13.3px Arial, which is neither of this product's two
     typefaces — so any button whose component set a size and a weight but not a
     family was quietly drawing in a third one. A comment's Edit and Delete sit
     side by side and are a link and a button_to; they were set in system-ui and
     in Arial respectively, at the same size, four pixels apart. Nothing looked
     broken. It looked like bad kerning.

     Most components already say `font: inherit` for exactly this reason. This
     is that decision made once, for the ones that forget — and only the family,
     so a component still chooses its own size and weight. */
  button, input, select, textarea { font-family: inherit; }

  a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }

  /* `turbo_stream_from` puts one of these in the page and it draws nothing —
     but an unknown element is display: inline, and <main> is a flex column, so
     it was blockified into a real child of that column with a real gap after
     it. Every page that subscribes to a broadcast therefore started 32px
     further down than every page that does not: Inbox, Today, Anytime,
     Projects and a task's own page sat one gap below Workspace and Your
     profile, for no reason anybody could see on the screen.

     Plumbing, and it should take up the room plumbing takes up. Hiding it
     costs nothing — the element does its work by being connected to the
     document, not by being laid out. */
  turbo-cable-stream-source { display: none; }

  kbd {
    font-family: var(--font-mono);
    font-size: var(--text-xs);
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    padding: 0.15em 0.45em;
    color: var(--ink-muted);
  }

  /* Never remove a focus ring without replacing it. Every action in this
     product must be reachable by keyboard.

     The ring is here at rest as well, transparent and at offset 0, and that is
     the whole trick. `outline: none` → `solid` is a discrete change with
     nothing in between, so a ring declared only under :focus-visible can never
     do anything but appear. Given somewhere to travel from, it lands on the
     control instead — which is the difference between a keyboard that is
     tolerated and one that feels aimed.

     --responds carries the press with it, so every control in the product
     answers a finger and a Tab key from one declaration. The catch is that
     `transition` is a shorthand and this selector has zero specificity: any
     component setting its own transition replaces this one entirely. Those
     append var(--responds) to their own list, and the ones that forgot are
     visible as the controls that do not move. */
  :where(a, button, input, select, textarea, summary, [tabindex]) {
    outline: 2.5px solid transparent;
    outline-offset: 0;
    transition: var(--responds);
  }

  :where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
    outline: var(--focus-ring);
    outline-offset: var(--focus-offset);
    border-radius: var(--radius-sm);
  }

  /* The press, once, for everything that is pressable.

     Named selectors rather than :where(button), because not everything that is
     a button should shrink under a finger. A task row is 64px of list with a
     stretched link over it and a scale on that is a different gesture
     entirely; the row answers with its tint, which it already did.

     Listed here for the same reason .label is listed here — it is one
     decision that several components share, and the alternative is the same
     two declarations copied into eight files and drifting. This sits in the
     base layer, so a component that genuinely needs a different press can
     still say so in its own file and win. */
  .button:active,
  .picker:active,
  .menu__item:active,
  .tag:active,
  .task__status:active,
  .task__who:active,
  .masthead__workspace:active,
  .masthead__you:active,
  .masthead__back:active,
  .viewmenu__button:active,
  .comment__action:active,
  .shortcuts__close:active,
  .list-end__find:active,
  .flash__close:active,
  .archive__summary:active,
  .palette__result:active {
    transform: var(--press);
    transition-duration: var(--press-down);
  }

  /* Small caps labels: the one place tracking is opened up rather than closed.
     
     This is the definition, and everything in the product that is a label
     joins it here rather than restating the same five declarations. They had
     drifted into six identical copies, which is how a scale stops being a
     scale — nothing had gone wrong yet, but nothing was stopping it either.
     
     A label names the thing beside it. It is never a heading: .timeline__heading
     is an <h2> because "Activity" opens a section of the document, and it is
     styled from here because it is read as a label. The tag says what it is in
     the outline; this says how it is set.

     A label that is also pressable is still a label. .comment__action and
     .shortcuts__close had grown their own copy of these five declarations in
     timeline.css and disagreed with this one about exactly one of them — 500
     where everything else in the product is 600 — which is the seventh copy
     and the first divergence, and neither was visible next to the other. They
     take their type from here now and keep only what makes them a button. */
  .label,
  .field label,
  .menu__label,
  .property__label,
  .rowaction__label,
  .timeline__heading,
  .palette__group,
  .comment__action,
  .shortcuts__close,
  .status,
  .role {
    font-size: var(--text-xs);
    font-weight: var(--weight-bold);
    letter-spacing: var(--tracking-label);
    text-transform: uppercase;
    color: var(--ink-faint);
  }

  /* Arriving, at its quietest. Under reduced motion this is what every
     arrival in the product collapses to: the thing still arrives, it simply
     arrives where it is rather than travelling there. Components name it in
     their own reduce branch rather than each inventing a fade. */
  @keyframes fade-in { from { opacity: 0; } }

  .visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }
}
