/* Generated by scripts/build.ts from css/components.css. Do not edit; change the source and run pnpm build. */

/* The server-rendered component layer (hub ui-standard §2): the account's layout.ts stylesheet as
   classes, on the roles in tokens.css. Plain class names, the account's own, so its markup moves over
   unchanged (D-5). Colours only through roles: test/components.test.ts fails on a hex, rgb() or hsl()
   literal here. Both layers are named so a product's own unlayered rules win without !important. */

@layer forspring.base, forspring.components;

@layer forspring.base {
  /* Shades the account had as extra tokens (--blue-deep links, --blue-hover, --tint), derived from
     the roles so they follow every product's accent and both themes. The account's --tint (the
     accent at 8%) is gone: no non-action state is filled with the accent, which can be red-ish. Declared wherever the accent can
     change, because a custom property resolves its var()s where it is declared. */
  :root,
  [data-product],
  [data-theme] {
    --_link: color-mix(in srgb, var(--primary) 70%, var(--foreground));
    --_hover: color-mix(in srgb, var(--primary) 80%, light-dark(var(--background), var(--foreground)));
    --_shadow: color-mix(in srgb, light-dark(var(--foreground), var(--background)) 25%, transparent);
    /* A control's line box is what its height leaves after the padding and the 1px borders, so the
       text sits in the middle of every control of a size, and a row of them shares a baseline. */
    --_control-line: calc(var(--control-height) - 2 * var(--space-3) - 2px);
    --_control-line-small: calc(var(--control-height-small) - 2 * var(--space-1) - 2px);
  }

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

  html {
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
  }

  body {
    margin: 0;
    background: var(--background);
    color: var(--body-foreground);
    font: 400 var(--text-content-body)/1.55 var(--font-sans);
    -webkit-font-smoothing: antialiased;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
  }

  h1,
  h2,
  h3 {
    color: var(--foreground);
    margin: 0;
    text-wrap: balance;
  }

  h1 {
    font: 800 clamp(var(--text-content-h1-min), 4.4vw, var(--text-content-h1))/1.05 var(--font-display);
    letter-spacing: -0.02em;
    margin-bottom: var(--space-3);
  }

  h2 {
    font: 800 var(--text-content-h2)/1.15 var(--font-display);
    letter-spacing: -0.01em;
    margin-bottom: var(--space-3);
  }

  h3 {
    font: 600 var(--text-content-h3)/1.3 var(--font-sans);
    margin-bottom: var(--space-2);
  }

  p {
    margin: 0 0 var(--space-4);
  }

  b,
  strong {
    color: var(--foreground);
    font-weight: 600;
  }

  section {
    margin-top: var(--space-10);
  }

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

  a:hover {
    color: var(--_hover);
  }

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

  label {
    color: var(--foreground);
  }

  /* Control geometry (D-14). Inputs, selects and buttons share one box per size: a 1px border, 12px
     of padding and an 18px line (15px type at 1.2) make --control-height, 44px, and min-height holds
     it when a font or a product's padding differs. Text sits at the same height in every one, so a
     row of them shares a baseline. Small controls and the bar's are --control-height-small, 32px. */

  /* A bare button is the primary action, as in the account. */
  button {
    font: 600 var(--text-content-body)/var(--_control-line) var(--font-sans);
    cursor: pointer;
    border-radius: var(--radius-button);
    min-height: var(--control-height);
    padding: var(--space-3) var(--space-5);
    border: 1px solid var(--primary);
    background: var(--primary);
    color: var(--primary-foreground);
    transition: background-color 0.15s, border-color 0.15s;
  }

  button:hover {
    background: var(--_hover);
    border-color: var(--_hover);
    color: var(--primary-foreground);
  }

  input,
  select,
  textarea {
    font: 400 var(--text-content-body)/var(--_control-line) var(--font-sans);
    min-height: var(--control-height);
    padding: var(--space-3);
    border: 1px solid var(--input);
    border-radius: var(--radius-input);
    background: var(--card);
    color: var(--foreground);
    min-width: 0;
    width: 100%;
  }

  textarea {
    line-height: var(--space-5);
    min-height: calc(var(--space-16) * 2);
    resize: vertical;
  }

  /* The select draws its own chevron, so it sits where the padding leaves room for it, in
     --muted-foreground, centred, the same in every browser. Two gradients, each a diagonal stroke in a
     5px tile, make the caret: no url() or data: image, so a page with img-src 'self' needs nothing
     more. The stops are a pixel soft on each side, which antialiases the strokes. appearance: none
     keeps the native control: keyboard, the phone's picker, the option list in the system's theme. */
  select {
    appearance: none;
    padding-inline-end: var(--space-8);
    background-image:
      linear-gradient(45deg, transparent calc(50% - 1.25px), var(--muted-foreground) calc(50% - 0.5px), var(--muted-foreground) calc(50% + 0.5px), transparent calc(50% + 1.25px)),
      linear-gradient(135deg, transparent calc(50% - 1.25px), var(--muted-foreground) calc(50% - 0.5px), var(--muted-foreground) calc(50% + 0.5px), transparent calc(50% + 1.25px));
    background-size: 5px 5px;
    background-position:
      right calc(var(--space-3) + 5px) center,
      right var(--space-3) center;
    background-repeat: no-repeat;
    text-overflow: ellipsis;
    cursor: pointer;
  }

  select:dir(rtl) {
    background-position:
      left var(--space-3) center,
      left calc(var(--space-3) + 5px) center;
  }

  /* A list box shows its options, so it needs no chevron or room for one. */
  select:is([multiple], [size]:not([size="1"])) {
    background-image: none;
    padding-inline-end: var(--space-3);
    cursor: default;
  }

  input:disabled,
  select:disabled,
  textarea:disabled {
    background-color: var(--muted);
    color: var(--muted-foreground);
    border-color: var(--border);
    cursor: not-allowed;
  }

  input:focus-visible,
  select:focus-visible,
  textarea:focus-visible {
    outline: 2px solid var(--ring);
    outline-offset: 0;
    border-color: var(--ring);
  }

  input[type="checkbox"],
  input[type="radio"] {
    width: 18px;
    height: 18px;
    min-height: 0;
    margin: 0;
    padding: 0;
    accent-color: var(--primary);
    flex: none;
  }

  input[aria-invalid="true"],
  select[aria-invalid="true"],
  textarea[aria-invalid="true"] {
    border-color: var(--danger);
  }

  fieldset {
    border: 0;
    padding: 0;
    margin: 0;
    display: flex;
    gap: var(--space-3) var(--space-5);
    flex-wrap: wrap;
  }

  legend {
    padding: 0;
    margin-bottom: var(--space-2);
    font-size: var(--text-chrome-body);
    font-weight: 600;
    color: var(--foreground);
  }

  fieldset label {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--text-content-body);
    min-height: var(--space-6);
  }

  table {
    width: 100%;
    border-collapse: collapse;
  }

  th,
  td {
    text-align: left;
    padding: var(--space-3) var(--space-4);
    border-bottom: 1px solid var(--border);
    vertical-align: middle;
  }

  tr:last-child td {
    border-bottom: 0;
  }

  th {
    font: 400 var(--text-chrome-meta)/1.3 var(--font-mono);
    color: var(--muted-foreground);
    background: var(--muted);
    white-space: nowrap;
  }

  /* The row a link pointed at: neutral, with the accent as an edge rule (see .notice). */
  tr:target td {
    background: var(--muted);
  }

  tr:target td:first-child {
    box-shadow: inset 3px 0 0 var(--primary);
  }

  main {
    flex: 1;
    padding-block: var(--space-11) var(--space-16);
  }

  @media (prefers-reduced-motion: reduce) {
    *,
    *::before,
    *::after {
      transition: none !important;
      animation: none !important;
    }
  }
}

@layer forspring.components {
  /* --- Page frame ---------------------------------------------------------------------------- */

  .wrap {
    width: 100%;
    max-width: 920px;
    margin: 0 auto;
    padding-inline: var(--space-5);
  }

  main.narrow {
    max-width: 480px;
    padding-top: max(var(--space-11), 8vh);
  }

  .skip {
    position: absolute;
    left: -9999px;
  }

  .skip:focus {
    left: var(--space-2);
    top: var(--space-2);
    z-index: 10;
    background: var(--primary);
    color: var(--primary-foreground);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-button);
  }

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

  /* --- Shell: the bar with the mark, "Forspring", the product, a switcher and the person -------- */

  .bar {
    border-bottom: 1px solid var(--border);
    background: var(--background);
  }

  .bar-inner {
    display: flex;
    align-items: center;
    gap: var(--space-3) var(--space-4);
    min-height: var(--space-16);
    flex-wrap: wrap;
    padding-block: var(--space-2);
  }

  /* Everything in the bar is a small control, 32px, centred on the wordmark's line: a select or an
     input there (an organisation picker) matches the switcher and a small button beside it. */
  .bar-inner :is(select, input:not([type="checkbox"], [type="radio"])) {
    width: auto;
    max-width: 16rem;
    min-height: var(--control-height-small);
    padding-block: var(--space-1);
    font-size: var(--text-content-small);
    line-height: var(--_control-line-small);
  }

  .brand {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    color: var(--foreground);
    text-decoration: none;
    border-radius: var(--radius-button);
    min-height: var(--space-11);
  }

  .brand:hover {
    color: var(--foreground);
  }

  .brand .mark {
    width: var(--space-7);
    height: var(--space-7);
    flex: none;
  }

  /* The doll's colour is --mark: the product's accent, ink on Forspring's own pages (hub D-101).
     The wordmark beside it stays ink in every product. */
  .brand .mark .fill {
    fill: var(--mark);
  }

  .brand .mark .coil {
    stroke: var(--mark);
  }

  .brand .word {
    font: 900 var(--text-content-h2)/1 var(--font-display);
    letter-spacing: -0.01em;
  }

  .brand .sub {
    font: 400 var(--text-chrome-meta)/1 var(--font-mono);
    color: var(--muted-foreground);
    display: inline-flex;
    align-items: center;
    min-height: var(--space-5);
    border-inline-start: 1px solid var(--input);
    padding-inline-start: var(--space-3);
    margin-inline-start: var(--space-1);
  }

  .spacer {
    flex: 1;
  }

  .who {
    font: 400 var(--text-chrome-meta)/1.2 var(--font-mono);
    color: var(--muted-foreground);
    overflow-wrap: anywhere;
  }

  /* The product switcher: a details element, so it opens with no script. */
  .switcher {
    position: relative;
  }

  .switcher > summary {
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--control-height-small);
    padding: var(--space-1) var(--space-3);
    border: 1px solid var(--input);
    border-radius: var(--radius-button);
    font: 400 var(--text-chrome-meta)/1.2 var(--font-mono);
    color: var(--muted-foreground);
    cursor: pointer;
  }

  .switcher > summary::-webkit-details-marker {
    display: none;
  }

  .switcher > summary::after {
    content: "";
    width: 6px;
    height: 6px;
    border-right: 1.5px solid currentColor;
    border-bottom: 1.5px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
  }

  .switcher > summary:hover,
  .switcher[open] > summary {
    color: var(--foreground);
    border-color: var(--foreground);
  }

  .switcher > ul {
    position: absolute;
    z-index: 5;
    top: calc(100% + var(--space-1));
    left: 0;
    min-width: 12rem;
    margin: 0;
    padding: var(--space-1);
    list-style: none;
    background: var(--popover);
    color: var(--popover-foreground);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    box-shadow: 0 var(--space-1) var(--space-4) var(--_shadow);
  }

  .switcher a {
    display: flex;
    align-items: center;
    min-height: var(--space-10);
    padding: 0 var(--space-3);
    border-radius: var(--radius-button);
    color: var(--foreground);
    text-decoration: none;
  }

  .switcher a:hover {
    background: var(--muted);
    color: var(--foreground);
  }

  .switcher a[aria-current] {
    font-weight: 600;
    box-shadow: inset 2px 0 0 var(--primary);
  }

  /* --- The bar's menus: org, products, the person (D-17) ------------------------------------ */

  /* Each is a details element like the switcher, so it opens with no script and a keyboard reaches
     it with Tab and opens it with Enter or Space. The panel holds a label, the links and a foot. */
  .bar-inner {
    position: relative;
  }

  .bar-menu > summary {
    max-width: 16rem;
  }

  .bar-menu-name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    color: var(--foreground);
    font-weight: 600;
    font-family: var(--font-sans);
    font-size: var(--text-chrome-body);
  }

  .bar-panel {
    position: absolute;
    z-index: 5;
    top: calc(100% + var(--space-1));
    left: 0;
    min-width: 18rem;
    max-width: 24rem;
    padding: var(--space-1);
    background: var(--popover);
    color: var(--popover-foreground);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    box-shadow: 0 var(--space-1) var(--space-4) var(--_shadow);
    font: 400 var(--text-chrome-body)/1.3 var(--font-sans);
  }

  .bar-panel ul {
    list-style: none;
    margin: 0;
    padding: 0;
  }

  .bar-panel a {
    gap: var(--space-3);
  }

  .bar-item-name {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
  }

  .bar-item-meta {
    font: 400 var(--text-chrome-meta)/1.2 var(--font-mono);
    color: var(--muted-foreground);
  }

  .bar-panel-label {
    margin: 0;
    padding: var(--space-2) var(--space-3) var(--space-1);
    font: 400 var(--text-chrome-label)/1.3 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted-foreground);
  }

  .bar-panel-foot {
    margin: var(--space-1) 0 0;
    padding-top: var(--space-1);
    border-top: 1px solid var(--border);
  }

  .bar-panel-foot a {
    color: var(--_link);
  }

  /* The user menu sits at the end of the bar, so its panel opens towards the start. */
  .user-menu > .bar-panel {
    left: auto;
    right: 0;
  }

  .user-menu > summary {
    justify-content: center;
    min-width: var(--control-height-small);
    padding: 0 var(--space-2);
    border-radius: 999px;
    background: var(--muted);
  }

  .user-menu > summary::after {
    content: none;
  }

  .avatar {
    font: 600 var(--text-chrome-meta)/1 var(--font-sans);
    letter-spacing: 0.02em;
    color: var(--foreground);
  }

  .user-head {
    display: grid;
    gap: var(--space-1);
    margin: 0 0 var(--space-1);
    padding: var(--space-3);
    border-bottom: 1px solid var(--border);
  }

  .user-name {
    font-weight: 600;
    color: var(--foreground);
  }

  .user-email,
  .user-role {
    font: 400 var(--text-chrome-meta)/1.3 var(--font-mono);
    color: var(--muted-foreground);
    overflow-wrap: anywhere;
  }

  .user-lang {
    display: flex;
    gap: var(--space-1);
    margin: var(--space-1) 0 0;
    padding-top: var(--space-1);
    border-top: 1px solid var(--border);
  }

  .switcher .user-lang a {
    flex: 1;
    justify-content: center;
  }

  .user-signout {
    margin: var(--space-1) 0 0;
    padding: var(--space-2) var(--space-1) var(--space-1);
    border-top: 1px solid var(--border);
  }

  /* --- Standard pages around signing in: choose an org, no org, refused (D-17) -------------- */

  .std-page > .list,
  .std-page > .std-people {
    margin-bottom: var(--space-4);
  }

  .std-page > .actions {
    margin-top: var(--space-2);
  }

  .std-label {
    margin: var(--space-6) 0 var(--space-2);
    font: 400 var(--text-chrome-label)/1.3 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted-foreground);
  }

  .std-people {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-2);
  }

  .std-people a {
    overflow-wrap: anywhere;
  }

  .std-page .meta {
    margin-bottom: var(--space-3);
  }

  .std-page .name .tag {
    margin-inline-start: var(--space-2);
    vertical-align: middle;
  }

  code {
    font-family: var(--font-mono);
    font-size: var(--text-content-small);
    overflow-wrap: anywhere;
  }

  /* --- Menu: a product's own sections, beside the page (D-13) -------------------------------- */

  /* With a menu the frame widens so the content keeps its measure beside it. The sidebar shows on a
     wide screen; on a narrow one the same menu folds under "Menu" (a details element, no script). */
  .has-menu .wrap {
    max-width: 1120px;
  }

  .app {
    flex: 1;
    display: grid;
    grid-template-columns: 13.5rem minmax(0, 1fr);
    gap: var(--space-12);
    align-items: start;
  }

  .app > main {
    min-width: 0;
    max-width: 760px;
  }

  .menu-side {
    position: sticky;
    top: 0;
    padding-block: var(--space-11) var(--space-8);
  }

  .menu-fold {
    display: none;
  }

  /* nav.menu, not .menu: a product's own details.menu (SiteSpring's account menu) must not become a grid. */
  nav.menu {
    display: grid;
    gap: var(--space-6);
    font: 400 var(--text-chrome-body)/1.3 var(--font-sans);
  }

  nav.menu ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-1);
  }

  .menu-label {
    display: block;
    margin: 0 0 var(--space-2);
    padding-inline: var(--space-3);
    font: 400 var(--text-chrome-label)/1.3 var(--font-mono);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--muted-foreground);
  }

  .menu-group a {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--space-8);
    padding: var(--space-1) var(--space-3);
    border-radius: var(--radius-button);
    color: var(--body-foreground);
    text-decoration: none;
  }

  .menu-group a:hover {
    background: var(--muted);
    color: var(--foreground);
  }

  /* Where the person is (the page, or the item it sits under): the muted surface, ink, and the
     accent only as an edge rule (D-5). */
  .menu-group a[aria-current] {
    background: var(--muted);
    color: var(--foreground);
    font-weight: 600;
    box-shadow: inset 2px 0 0 var(--primary);
  }

  .menu-text {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
  }

  .menu-badge {
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    font: 400 var(--text-chrome-meta)/1 var(--font-mono);
    color: var(--muted-foreground);
    font-variant-numeric: tabular-nums;
  }

  /* The context: which organisation the menu is for, and a switcher when there are others. */
  .menu-context {
    position: relative;
    display: grid;
    gap: var(--space-1);
    padding: var(--space-2) var(--space-3);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    background: var(--card);
  }

  .menu-context .menu-label {
    margin: 0;
    padding: 0;
  }

  .menu-context-name {
    font-weight: 600;
    color: var(--foreground);
    overflow-wrap: anywhere;
  }

  details.menu-context {
    padding: 0;
  }

  details.menu-context > summary {
    list-style: none;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    column-gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-card);
    cursor: pointer;
  }

  details.menu-context > summary::-webkit-details-marker {
    display: none;
  }

  details.menu-context > summary > * {
    grid-column: 1;
  }

  details.menu-context > summary::after {
    content: "";
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: center;
    width: 6px;
    height: 6px;
    border-right: 1.5px solid var(--muted-foreground);
    border-bottom: 1.5px solid var(--muted-foreground);
    transform: translateY(-2px) rotate(45deg);
  }

  details.menu-context > summary:hover {
    background: var(--muted);
  }

  details.menu-context > ul {
    position: absolute;
    z-index: 5;
    top: calc(100% + var(--space-1));
    left: 0;
    right: 0;
    padding: var(--space-1);
    background: var(--popover);
    color: var(--popover-foreground);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    box-shadow: 0 var(--space-1) var(--space-4) var(--_shadow);
  }

  details.menu-context a {
    display: flex;
    align-items: center;
    min-height: var(--space-8);
    padding: 0 var(--space-3);
    border-radius: var(--radius-button);
    color: var(--foreground);
    text-decoration: none;
  }

  details.menu-context a:hover {
    background: var(--muted);
  }

  details.menu-context a[aria-current="true"] {
    font-weight: 600;
    box-shadow: inset 2px 0 0 var(--primary);
  }

  /* --- Crumbs: the page's parents, quiet, before its h1 ------------------------------------- */

  .crumbs ol {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-1) var(--space-2);
    margin: 0 0 var(--space-3);
    padding: 0;
    font: 400 var(--text-chrome-meta)/1.4 var(--font-mono);
  }

  .crumbs li {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
  }

  .crumbs li + li::before {
    content: "/";
    color: var(--input);
  }

  .crumbs a {
    display: inline-flex;
    align-items: center;
    min-height: var(--space-6);
    color: var(--muted-foreground);
    text-decoration: none;
  }

  .crumbs a:hover {
    color: var(--foreground);
    text-decoration: underline;
  }

  /* --- Signal: a monitored thing's state as a traffic light (D-13) -------------------------- */

  /* The word carries the meaning; the mark repeats it in colour and in shape, so red and green are
     told apart without colour: up a dot, late a triangle, down a diamond, not judged a hollow ring. */
  .signal {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    font: 500 var(--text-chrome-body)/1.2 var(--font-sans);
    color: var(--foreground);
    white-space: nowrap;
  }

  .signal-mark {
    flex: none;
    display: inline-block;
    width: 10px;
    height: 10px;
    background: var(--signal-off);
  }

  .signal-mark.ok {
    border-radius: 999px;
    background: var(--signal-ok);
  }

  .signal-mark.warn {
    width: 11px;
    clip-path: polygon(50% 0, 100% 100%, 0 100%);
    background: var(--signal-warn);
  }

  .signal-mark.down {
    clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
    background: var(--signal-down);
  }

  .signal-mark.off {
    border-radius: 999px;
    background: transparent;
    border: 2px solid var(--signal-off);
  }

  /* --- Footer --------------------------------------------------------------------------------- */

  footer {
    border-top: 1px solid var(--border);
    font: 400 var(--text-chrome-meta)/1.5 var(--font-mono);
    color: var(--muted-foreground);
  }

  .foot {
    display: flex;
    gap: var(--space-2) var(--space-5);
    flex-wrap: wrap;
    padding-block: var(--space-5) var(--space-7);
  }

  footer a {
    color: var(--muted-foreground);
  }

  footer a:hover {
    color: var(--foreground);
  }

  /* --- Text ----------------------------------------------------------------------------------- */

  h1 + .list,
  h1 + .table-wrap {
    margin-top: var(--space-6);
  }

  .kicker {
    font: 400 var(--text-content-small)/1.4 var(--font-mono);
    color: var(--primary);
    margin: 0 0 var(--space-3);
  }

  .lede {
    font-size: var(--text-content-lede);
    color: var(--muted-foreground);
    margin-bottom: var(--space-7);
  }

  .muted {
    color: var(--muted-foreground);
  }

  .small {
    font-size: var(--text-content-small);
  }

  .fine {
    font-size: var(--text-content-small);
    color: var(--muted-foreground);
    margin: var(--space-4) 0 0;
  }

  .fine + .fine {
    margin-top: var(--space-2);
  }

  .fine a {
    color: inherit;
  }

  .fine a:hover {
    color: var(--foreground);
  }

  .back {
    display: inline-block;
    font: 400 var(--text-content-small)/1.4 var(--font-mono);
    color: var(--muted-foreground);
    text-decoration: none;
    margin-bottom: var(--space-6);
  }

  .back:hover {
    color: var(--foreground);
  }

  .num {
    font-variant-numeric: tabular-nums;
  }

  th.num,
  td.num {
    text-align: right;
  }

  .stack > * + * {
    margin-top: var(--space-3);
  }

  /* --- Card and list -------------------------------------------------------------------------- */

  .card {
    background: var(--card);
    color: var(--card-foreground);
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    padding: var(--space-7);
  }

  .card h1 {
    font-size: var(--text-content-h1-min);
  }

  ul.list {
    list-style: none;
    margin: 0;
    padding: 0;
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    background: var(--card);
  }

  ul.list li {
    display: flex;
    align-items: center;
    gap: var(--space-3) var(--space-4);
    padding: var(--space-4) var(--space-5);
    flex-wrap: wrap;
  }

  ul.list li + li {
    border-top: 1px solid var(--border);
  }

  .grow {
    flex: 1;
    min-width: 12rem;
  }

  .name {
    font-weight: 600;
    color: var(--foreground);
  }

  .meta {
    font-size: var(--text-content-small);
    color: var(--muted-foreground);
    font-variant-numeric: tabular-nums;
  }

  .go {
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
  }

  .go::after {
    content: "\00a0\203A";
  }

  /* --- Buttons -------------------------------------------------------------------------------- */

  .button {
    font: 600 var(--text-content-body)/var(--_control-line) var(--font-sans);
    cursor: pointer;
    border-radius: var(--radius-button);
    min-height: var(--control-height);
    padding: var(--space-3) var(--space-5);
    border: 1px solid var(--primary);
    background: var(--primary);
    color: var(--primary-foreground);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    text-align: center;
    transition: background-color 0.15s, border-color 0.15s;
  }

  .button:hover {
    background: var(--_hover);
    border-color: var(--_hover);
    color: var(--primary-foreground);
  }

  :is(button, .button).ghost {
    background: transparent;
    color: var(--foreground);
    border-color: var(--input);
  }

  :is(button, .button).ghost:hover {
    border-color: var(--foreground);
    color: var(--foreground);
    background: transparent;
  }

  /* Destructive, and never the loudest thing on the page: danger text on the surface. */
  :is(button, .button).danger {
    background: transparent;
    color: var(--danger);
    border-color: var(--danger);
  }

  :is(button, .button).danger:hover {
    background: color-mix(in srgb, var(--danger) 8%, transparent);
    color: var(--danger);
    border-color: var(--danger);
  }

  :is(button, .button).small {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: var(--control-height-small);
    padding: var(--space-1) var(--space-3);
    font-size: var(--text-content-small);
    line-height: var(--_control-line-small);
  }

  /* A small input or select: the small button's box, beside it in a toolbar. */
  :is(input, select).small {
    min-height: var(--control-height-small);
    padding-block: var(--space-1);
    line-height: var(--_control-line-small);
  }

  :is(button, .button).wide {
    width: 100%;
  }

  :is(button, .button):disabled,
  :is(button, .button)[aria-disabled="true"] {
    cursor: not-allowed;
    opacity: 0.55;
  }

  form.inline {
    display: inline;
    margin: 0;
  }

  td form.inline {
    display: inline-flex;
    vertical-align: middle;
  }

  .actions {
    display: inline-flex;
    gap: var(--space-2);
    flex-wrap: wrap;
  }

  /* Controls in a row: a search, a filter, its buttons. They share a height, so they share a line;
     a text input takes the room that is left. */
  .toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-2);
  }

  .toolbar > :is(input, select) {
    width: auto;
  }

  .toolbar > input:not([type="checkbox"], [type="radio"]) {
    flex: 1 1 12rem;
  }

  /* --- Forms ---------------------------------------------------------------------------------- */

  .form {
    display: grid;
    gap: var(--space-4);
    max-width: 30rem;
  }

  .form p {
    margin: 0;
  }

  .field {
    display: grid;
    gap: var(--space-2);
    font-size: var(--text-chrome-body);
    font-weight: 600;
    color: var(--foreground);
  }

  .hint {
    margin: 0;
    font-size: var(--text-content-small);
    font-weight: 400;
    color: var(--muted-foreground);
  }

  .field-error {
    margin: -4px 0 0;
    font-size: var(--text-content-small);
    font-weight: 400;
    color: var(--danger);
  }

  .field > .field-error {
    margin: 0;
  }

  .check {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    min-height: var(--space-6);
  }

  /* --- Table ---------------------------------------------------------------------------------- */

  /* Wider than the page scrolls inside the frame, never clipped. Give the wrap tabindex="0", a role
     of region and a label, so a keyboard can reach and scroll it; the shadows at the edges show
     there is more (they are covered while the content sits flush with that edge). */
  .table-wrap {
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    overflow-x: auto;
    background:
      linear-gradient(to right, var(--card) 30%, transparent) left / var(--space-10) 100% no-repeat local,
      linear-gradient(to left, var(--card) 30%, transparent) right / var(--space-10) 100% no-repeat local,
      radial-gradient(farthest-side at 0 50%, var(--_shadow), transparent) left / var(--space-3) 100% no-repeat scroll,
      radial-gradient(farthest-side at 100% 50%, var(--_shadow), transparent) right / var(--space-3) 100% no-repeat scroll,
      var(--card);
  }

  .table-wrap:focus-visible {
    outline-offset: 2px;
  }

  .table-wrap caption {
    text-align: left;
    padding: var(--space-3) var(--space-4);
    font-weight: 600;
    color: var(--foreground);
  }

  td .email {
    color: var(--muted-foreground);
    font-size: var(--text-content-small);
    overflow-wrap: anywhere;
  }

  .phone-only {
    display: none;
  }

  /* --- Switch: a button[role=switch] whose aria-checked the server sets --------------------- */

  .switch {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    background: transparent;
    color: var(--muted-foreground);
    border: 0;
    padding: var(--space-1) 0;
    font-weight: 400;
    font-size: var(--text-content-small);
    min-height: var(--space-6);
  }

  .switch:hover {
    background: transparent;
    color: var(--foreground);
  }

  .switch .track {
    width: var(--space-10);
    height: var(--space-6);
    border-radius: 999px;
    background: var(--input);
    position: relative;
    flex: none;
    transition: background-color 0.15s;
  }

  .switch .track::after {
    content: "";
    position: absolute;
    top: var(--space-1);
    left: var(--space-1);
    width: var(--space-4);
    height: var(--space-4);
    border-radius: 999px;
    background: light-dark(var(--card), var(--foreground));
    box-shadow: 0 1px 2px var(--_shadow);
    transition: transform 0.15s;
  }

  .switch[aria-checked="true"] .track {
    background: var(--primary);
  }

  .switch[aria-checked="true"] .track::after {
    transform: translateX(var(--space-4));
  }

  .switch[aria-checked="true"] .state {
    color: var(--foreground);
  }

  .switch:focus-visible {
    outline-offset: 2px;
    border-radius: 999px;
  }

  /* --- Notice: what just happened, in words; the colour only repeats it --------------------- */

  /* A plain notice is neutral, with the accent only as a thin rule at its edge: an accent can be
     red-ish (SiteSpring's terracotta, PulseSpring's magenta), and at notice strength it read as an
     error (controller review of hen, 2026-10-10). Only status notices take a status colour. */
  .notice {
    border: 1px solid var(--border);
    border-left: 3px solid var(--primary);
    background: var(--card);
    color: var(--foreground);
    border-radius: var(--radius-card);
    padding: var(--space-3) var(--space-4);
    margin: 0 0 var(--space-6);
  }

  .notice.success {
    border: 1px solid var(--success);
    background: color-mix(in srgb, var(--success) 9%, var(--card));
  }

  .notice.warning {
    border: 1px solid var(--warning);
    background: color-mix(in srgb, var(--warning) 9%, var(--card));
  }

  .notice.error {
    border: 1px solid var(--danger);
    background: color-mix(in srgb, var(--danger) 9%, var(--card));
  }

  .notice > :last-child {
    margin-bottom: 0;
  }

  .notice-title {
    display: block;
    font-weight: 600;
    color: var(--foreground);
  }

  /* A monitored state: the neutral card, the signal as the edge rule and its mark before the title. */
  .notice[class*="signal-"] {
    border: 1px solid var(--border);
    background: var(--card);
    color: var(--foreground);
  }

  .notice.signal-ok {
    border-left: 3px solid var(--signal-ok);
  }

  .notice.signal-warn {
    border-left: 3px solid var(--signal-warn);
  }

  .notice.signal-down {
    border-left: 3px solid var(--signal-down);
  }

  .notice.signal-off {
    border-left: 3px solid var(--signal-off);
  }

  .notice[class*="signal-"] .notice-title {
    display: flex;
    align-items: center;
    gap: var(--space-2);
  }

  /* --- Tag ------------------------------------------------------------------------------------ */

  .tag {
    font: 400 var(--text-chrome-label)/1.4 var(--font-mono);
    color: var(--muted-foreground);
    border: 1px solid var(--input);
    border-radius: 999px;
    display: inline-flex;
    align-items: center;
    min-height: var(--space-5);
    padding: 0 var(--space-2);
    white-space: nowrap;
  }

  /* "Ny", "Beta": neutral text with an accent dot, never an accent outline, for the same reason as
     the plain notice. */
  .tag.primary {
    color: var(--foreground);
  }

  .tag.primary::before {
    content: "";
    display: inline-block;
    width: 6px;
    height: 6px;
    margin-inline-end: var(--space-1);
    border-radius: 999px;
    background: var(--primary);
  }

  .tag.success {
    color: var(--success);
    border-color: var(--success);
  }

  .tag.warning {
    color: var(--warning);
    border-color: var(--warning);
  }

  .tag.danger {
    color: var(--danger);
    border-color: var(--danger);
  }

  /* --- States: empty, loading, failed (Canonify DESIGN-SURFACE §3) ------------------------- */

  /* A state takes the footprint of the list or table it stands in for, so nothing jumps when the
     data arrives. Empty says there is nothing (or nothing matching a filter); failed says the read
     failed and never claims there is nothing; loading shows the shape of what is coming. */
  .data-state {
    border: 1px solid var(--border);
    border-radius: var(--radius-card);
    background: var(--card);
    padding: var(--space-8) var(--space-7);
    min-height: calc(var(--space-16) * 2);
  }

  .data-state-title {
    margin: 0 0 var(--space-1);
    font: 600 var(--text-content-lede)/1.4 var(--font-sans);
    color: var(--foreground);
  }

  .data-state-text {
    margin: 0;
    color: var(--muted-foreground);
    max-width: 40rem;
  }

  .data-state-actions {
    margin-top: var(--space-4);
    display: flex;
    gap: var(--space-2);
    flex-wrap: wrap;
  }

  .data-state.failed {
    border-color: var(--danger);
  }

  .data-state.failed .data-state-title {
    color: var(--danger);
  }

  .data-state.loading {
    display: grid;
    gap: var(--space-3);
    align-content: start;
  }

  .skeleton {
    display: block;
    height: var(--space-3);
    border-radius: var(--radius-button);
    background: var(--border);
    animation: forspring-pulse 1.4s ease-in-out infinite;
  }

  .skeleton:nth-child(3n + 1) {
    width: 60%;
  }

  .skeleton:nth-child(3n + 2) {
    width: 85%;
  }

  .skeleton:nth-child(3n) {
    width: 40%;
  }

  @keyframes forspring-pulse {
    50% {
      opacity: 0.45;
    }
  }

  /* --- The "or" divider between two ways to sign in ----------------------------------------- */

  .or {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    margin: var(--space-5) 0;
    font: 400 var(--text-chrome-meta)/1 var(--font-mono);
    color: var(--muted-foreground);
  }

  .or::before,
  .or::after {
    content: "";
    flex: 1;
    border-top: 1px solid var(--border);
  }

  /* Below a tablet's width the sidebar folds: one column, and the menu under "Menu" above main. */
  @media (max-width: 800px) {
    .app {
      display: block;
    }

    nav.menu-side {
      display: none;
    }

    .menu-fold {
      display: block;
      margin-top: var(--space-4);
      border: 1px solid var(--border);
      border-radius: var(--radius-card);
      background: var(--card);
    }

    .menu-fold > summary {
      list-style: none;
      display: flex;
      align-items: center;
      gap: var(--space-3);
      min-height: var(--space-11);
      padding: 0 var(--space-4);
      font: 600 var(--text-chrome-body)/1.2 var(--font-sans);
      color: var(--foreground);
      cursor: pointer;
    }

    .menu-fold > summary::-webkit-details-marker {
      display: none;
    }

    .menu-fold > summary::after {
      content: "";
      margin-left: auto;
      width: 7px;
      height: 7px;
      border-right: 1.5px solid currentColor;
      border-bottom: 1.5px solid currentColor;
      transform: translateY(-2px) rotate(45deg);
    }

    .menu-fold[open] > summary::after {
      transform: translateY(2px) rotate(225deg);
    }

    .menu-fold-current {
      font-weight: 400;
      color: var(--muted-foreground);
    }

    .menu-fold > .menu {
      padding: var(--space-2) var(--space-2) var(--space-4);
      border-top: 1px solid var(--border);
    }

    .menu-fold .menu-group a {
      min-height: var(--space-11);
    }
  }

  /* --- Phone ---------------------------------------------------------------------------------- */

  /* On a phone the primary controls grow to 44px, the person's address leaves the bar, and tables
     drop the columns marked to go. */
  @media (max-width: 560px) {
    .wrap {
      padding-inline: var(--space-4);
    }

    main {
      padding-block: var(--space-7) var(--space-12);
    }

    .who {
      display: none;
    }

    /* The bar's panels open full width under the bar, so none runs off a 380px screen. */
    .bar-menu {
      position: static;
    }

    .bar-panel,
    .user-menu > .bar-panel {
      left: var(--space-4);
      right: var(--space-4);
      top: calc(100% - var(--space-1));
      min-width: 0;
      max-width: none;
    }

    .bar-menu > summary {
      max-width: 11rem;
    }

    .user-menu > summary {
      min-width: var(--control-touch);
    }

    .bar-panel a {
      min-height: var(--control-touch);
    }

    .brand .word {
      font-size: var(--text-content-h3);
    }

    .card {
      padding: var(--space-6) var(--space-5);
    }

    .grow {
      min-width: 8rem;
    }

    th,
    td {
      padding: var(--space-2) var(--space-3);
    }

    /* Text links that stand alone get a 24px target where fingers are used. */
    .go,
    footer a {
      display: inline-flex;
      align-items: center;
      min-height: var(--space-6);
    }

    .phone-hide {
      display: none;
    }

    .phone-only {
      display: inline;
    }

    .switch {
      min-height: var(--space-11);
    }

    .switch .state {
      display: none;
    }

    ul.list li {
      padding: var(--space-3) var(--space-4);
    }

    .data-state {
      padding: var(--space-6) var(--space-5);
    }

    /* Small controls and the bar's grow to the touch floor; the default size is already there. */
    :is(button, .button):not(.switch, .gsi),
    :is(input, select):not([type="checkbox"], [type="radio"]),
    .bar-inner :is(select, input:not([type="checkbox"], [type="radio"])),
    .switcher > summary {
      min-height: var(--control-touch);
    }

    /* At the touch floor a small control takes the default box, keeping its smaller type, so its
       text stays in the middle. */
    :is(button, .button, input, select).small,
    .bar-inner :is(select, input:not([type="checkbox"], [type="radio"])) {
      padding-block: var(--space-3);
      line-height: calc(var(--control-touch) - 2 * var(--space-3) - 2px);
    }
  }
}
