/*
  THE FAMILY STYLE FILE.

  One set of visual tokens and one set of components, mirrored into every
  application on the channel the switcher and the sign-in modules already use.
  PreciseProcess/docs/specs/2026-09-04-shared-style-file.md is the design this
  implements, and STANDARDS.md section 13 is the ruling behind it.

  ── ADDING THIS FILE TO A PAGE CHANGES NOTHING ON THAT PAGE ─────────────────

  That is the single most important property of this file and it is deliberate.
  There is not one bare element selector here. No rule matches `button`, `input`,
  `h1` or `a`. Everything is either a custom property, which is additive and
  inert until something reads it, or a class beginning `px-`, which is inert
  until something opts in.

  The reason is that this file lands in eight applications at once. A bare
  `button` rule would restyle every screen in the estate in a single sync, with
  no review of any of them, and the first anyone would learn of it is a customer
  looking at a broken page. Adoption is therefore screen by screen and deliberate,
  and the file can ship everywhere long before any screen uses it.

  ── WHY THESE VALUES AND NOT OTHERS ────────────────────────────────────────

  Almost nothing here is new. The neutral scale is PreciseSignIn's, already in
  service in the family's front door. The accent scale is PreciseInsights'
  existing teal tokens, which PreciseTodo independently adopted. A survey of
  every stylesheet in the estate on 2026-09-04 found six different teals, one
  blue and one orange in use as accents. Three of those six could not carry
  white text at an accessible contrast, so they were never real candidates for
  a button color whatever anyone felt about them.

  ── THE NAMING, AND WHY IT IS UGLY ON PURPOSE ──────────────────────────────

  Every name starts `px-`. The applications already disagree about `--teal`,
  which is exactly why an unprefixed name here would be a collision rather than
  a standard. An application keeps its own tokens and adopts these alongside
  them, so the two can coexist during a migration that will take months.
*/

/* ══ TOKENS ═══════════════════════════════════════════════════════════════ */

:root {
  /*
    THE ACCENT. One color for the whole family, which is Paul's ruling of
    2026-09-04 recorded in STANDARDS.md section 13.

    The four values below are one scale, not four decisions. Base carries white
    text. Hover is the pressed and hovered state. Soft is a tinted background
    for a selected row or a quiet panel. Border is the line around a soft area.
  */
  --px-accent: #277A74;
  --px-accent-hover: #1D5B57;
  --px-accent-soft: #EAF6F4;
  --px-accent-border: #9AD3CC;
  --px-accent-contrast: #FFFFFF;

  /* Ink, from darkest to lightest. Body text, secondary text, hint text. */
  --px-ink: #1C1E21;
  --px-ink-2: #5A6169;
  --px-ink-3: #68717A;

  /* Surfaces. Ground is the page behind the cards. Card is the card. */
  --px-ground: #F4F5F7;
  --px-card: #FFFFFF;
  --px-rule: #E2E5E9;

  /*
    STATUS COLORS. Each one carries white text at an accessible contrast, so a
    status can be a filled badge as well as a word.
  */
  --px-good: #2C6A4C;
  --px-good-soft: #EAF5EF;
  --px-warn: #8A6314;
  --px-warn-soft: #FBF3E2;
  --px-bad: #9B3B33;
  --px-bad-soft: #FBEDEC;

  /*
    TYPE. A five-step scale, no more, because every extra step is a decision
    somebody has to make on every screen. Sizes are in rem so a reader who has
    set a larger default text size in their browser gets one.
  */
  --px-text-xs: 0.75rem;
  --px-text-sm: 0.8125rem;
  --px-text: 0.9375rem;
  --px-text-lg: 1.125rem;
  --px-text-xl: 1.5rem;
  --px-line: 1.5;
  --px-line-tight: 1.25;

  /* Spacing, on a four-pixel rhythm. */
  --px-space-1: 4px;
  --px-space-2: 8px;
  --px-space-3: 12px;
  --px-space-4: 16px;
  --px-space-5: 24px;
  --px-space-6: 32px;

  --px-radius: 6px;
  --px-radius-lg: 10px;

  --px-shadow: 0 1px 2px rgba(28, 30, 33, 0.06), 0 1px 3px rgba(28, 30, 33, 0.08);
  --px-shadow-lg: 0 4px 12px rgba(28, 30, 33, 0.10);

  /*
    THE FOCUS RING. One ring, everywhere, for every control. A person moving
    through a form with the keyboard must always be able to see where they are,
    and per-component focus styling is how that gets lost on the one screen
    nobody tested.
  */
  --px-focus: 0 0 0 3px rgba(39, 122, 116, 0.35);

  --px-duration: 120ms;
}

/*
  DARK MODE. The tokens are redefined and nothing else is, so every component
  below follows automatically.

  An application that has made an explicit choice sets data-px-theme on its root
  element and that choice wins in both directions. An application that has not
  follows the reader's own system setting. PreciseTodo already ships a dark mode
  of its own; these tokens are additive and do not disturb it.
*/
@media (prefers-color-scheme: dark) {
  :root:not([data-px-theme="light"]) {
    --px-accent: #6FCFC6;
    --px-accent-hover: #8FDDD5;
    --px-accent-soft: #14312F;
    --px-accent-border: #2B5F5A;
    --px-accent-contrast: #08211F;

    --px-ink: #E9ECEF;
    --px-ink-2: #A9B2BB;
    --px-ink-3: #818A93;

    --px-ground: #16181B;
    --px-card: #1F2226;
    --px-rule: #333941;

    --px-good: #6FCB98;
    --px-good-soft: #12291E;
    --px-warn: #E0B54A;
    --px-warn-soft: #2C2412;
    --px-bad: #E58C84;
    --px-bad-soft: #2E1B19;

    --px-shadow: 0 1px 2px rgba(0, 0, 0, 0.40), 0 1px 3px rgba(0, 0, 0, 0.30);
    --px-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45);
    --px-focus: 0 0 0 3px rgba(111, 207, 198, 0.40);
  }
}

:root[data-px-theme="dark"] {
  --px-accent: #6FCFC6;
  --px-accent-hover: #8FDDD5;
  --px-accent-soft: #14312F;
  --px-accent-border: #2B5F5A;
  --px-accent-contrast: #08211F;

  --px-ink: #E9ECEF;
  --px-ink-2: #A9B2BB;
  --px-ink-3: #818A93;

  --px-ground: #16181B;
  --px-card: #1F2226;
  --px-rule: #333941;

  --px-good: #6FCB98;
  --px-good-soft: #12291E;
  --px-warn: #E0B54A;
  --px-warn-soft: #2C2412;
  --px-bad: #E58C84;
  --px-bad-soft: #2E1B19;

  --px-shadow: 0 1px 2px rgba(0, 0, 0, 0.40), 0 1px 3px rgba(0, 0, 0, 0.30);
  --px-shadow-lg: 0 4px 12px rgba(0, 0, 0, 0.45);
  --px-focus: 0 0 0 3px rgba(111, 207, 198, 0.40);
}

/* ══ COMPONENTS, ALL OPT IN ═══════════════════════════════════════════════ */

/*
  NO font-family IS SET ANYWHERE IN THIS FILE, which is the same decision the
  switcher made and for the same reason. A component inherits whatever the host
  application already uses, so it reads as part of that page rather than as a
  widget somebody pasted in.
*/

/* ── Buttons ───────────────────────────────────────────────────────────── */

.px-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--px-space-2);
  padding: var(--px-space-2) var(--px-space-4);
  border: 1px solid transparent;
  border-radius: var(--px-radius);
  font: inherit;
  font-size: var(--px-text-sm);
  font-weight: 600;
  line-height: var(--px-line-tight);
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--px-duration), border-color var(--px-duration);
}

.px-btn:focus-visible {
  outline: none;
  box-shadow: var(--px-focus);
}

.px-btn[disabled],
.px-btn[aria-disabled="true"] {
  opacity: 0.55;
  cursor: not-allowed;
}

.px-btn-primary {
  background: var(--px-accent);
  color: var(--px-accent-contrast);
}

.px-btn-primary:hover:not([disabled]):not([aria-disabled="true"]) {
  background: var(--px-accent-hover);
}

.px-btn-secondary {
  background: var(--px-card);
  border-color: var(--px-rule);
  color: var(--px-ink);
}

.px-btn-secondary:hover:not([disabled]):not([aria-disabled="true"]) {
  background: var(--px-ground);
}

.px-btn-quiet {
  background: transparent;
  color: var(--px-ink-2);
}

.px-btn-quiet:hover:not([disabled]):not([aria-disabled="true"]) {
  background: var(--px-ground);
  color: var(--px-ink);
}

/*
  THE DESTRUCTIVE BUTTON IS DELIBERATELY NOT A FILLED RED ONE.

  A filled red button is the most eye-catching thing on the screen, which is
  exactly wrong for the action a person is most likely to regret. It is outlined
  until the pointer is over it, so it does not attract the accidental click, and
  it is unmistakable once deliberately approached.
*/
.px-btn-danger {
  background: var(--px-card);
  border-color: var(--px-bad);
  color: var(--px-bad);
}

.px-btn-danger:hover:not([disabled]):not([aria-disabled="true"]) {
  background: var(--px-bad);
  color: var(--px-card);
}

/* ── Form fields ───────────────────────────────────────────────────────── */

.px-field {
  display: block;
  margin-bottom: var(--px-space-4);
}

.px-label {
  display: block;
  margin-bottom: var(--px-space-1);
  font-size: var(--px-text-sm);
  font-weight: 600;
  color: var(--px-ink);
}

/*
  THE HINT SITS ABOVE THE INPUT, NOT BELOW IT.

  A hint printed under a field is read after the person has already answered,
  which is too late to be help. Anything explaining how to fill a field in goes
  here, before it.
*/
.px-hint {
  display: block;
  margin-bottom: var(--px-space-2);
  font-size: var(--px-text-sm);
  font-weight: 400;
  color: var(--px-ink-2);
  line-height: var(--px-line);
}

.px-input,
.px-select,
.px-textarea {
  display: block;
  width: 100%;
  box-sizing: border-box;
  padding: var(--px-space-2) var(--px-space-3);
  border: 1px solid var(--px-rule);
  border-radius: var(--px-radius);
  background: var(--px-card);
  color: var(--px-ink);
  font: inherit;
  font-size: var(--px-text);
  line-height: var(--px-line);
}

.px-textarea {
  min-height: 6rem;
  resize: vertical;
}

.px-input:focus-visible,
.px-select:focus-visible,
.px-textarea:focus-visible {
  outline: none;
  border-color: var(--px-accent);
  box-shadow: var(--px-focus);
}

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

/*
  THE ERROR MESSAGE CARRIES A WORD, NOT ONLY A COLOR. Point this at the field
  with aria-describedby so it is announced rather than merely displayed.
*/
.px-error {
  display: block;
  margin-top: var(--px-space-1);
  font-size: var(--px-text-sm);
  color: var(--px-bad);
}

/* ── Panels and notices ────────────────────────────────────────────────── */

.px-card {
  background: var(--px-card);
  border: 1px solid var(--px-rule);
  border-radius: var(--px-radius-lg);
  box-shadow: var(--px-shadow);
  padding: var(--px-space-5);
}

.px-notice {
  display: flex;
  gap: var(--px-space-3);
  padding: var(--px-space-3) var(--px-space-4);
  border: 1px solid var(--px-rule);
  border-left-width: 3px;
  border-radius: var(--px-radius);
  background: var(--px-ground);
  color: var(--px-ink);
  font-size: var(--px-text-sm);
  line-height: var(--px-line);
}

.px-notice-good {
  background: var(--px-good-soft);
  border-color: var(--px-rule);
  border-left-color: var(--px-good);
}

.px-notice-warn {
  background: var(--px-warn-soft);
  border-color: var(--px-rule);
  border-left-color: var(--px-warn);
}

.px-notice-bad {
  background: var(--px-bad-soft);
  border-color: var(--px-rule);
  border-left-color: var(--px-bad);
}

.px-notice-info {
  background: var(--px-accent-soft);
  border-color: var(--px-accent-border);
  border-left-color: var(--px-accent);
}

/* ── The delete safely pattern ─────────────────────────────────────────── */

/*
  ONE CONFIRMATION PATTERN FOR THE WHOLE FAMILY, which is item 3 of the build
  plan's section 8 and a safety fix rather than a decoration one.

  THE RULES THIS ENCODES, WHICH MATTER MORE THAN THE COLORS.

  Say what will be destroyed, by name, not "this item". Say what else goes with
  it, because a person deleting a folder rarely means to delete its contents and
  usually does. Say whether it can be undone, in words, and say so plainly when
  it cannot. The confirming button carries the verb, so it reads "Delete the
  September campaign" rather than "OK", because a person clicking OK is agreeing
  to a question they have often stopped reading. The way out is a real button
  and it comes first in the source, so keyboard focus lands on the safe choice.
*/
.px-confirm {
  border: 1px solid var(--px-bad);
  border-radius: var(--px-radius-lg);
  background: var(--px-card);
  box-shadow: var(--px-shadow-lg);
  padding: var(--px-space-5);
  max-width: 32rem;
}

.px-confirm-title {
  margin: 0 0 var(--px-space-2);
  font-size: var(--px-text-lg);
  font-weight: 700;
  line-height: var(--px-line-tight);
  color: var(--px-ink);
}

.px-confirm-body {
  margin: 0 0 var(--px-space-4);
  font-size: var(--px-text);
  line-height: var(--px-line);
  color: var(--px-ink-2);
}

/* What else is destroyed alongside the named thing. */
.px-confirm-consequences {
  margin: 0 0 var(--px-space-4);
  padding: var(--px-space-3) var(--px-space-4);
  border-radius: var(--px-radius);
  background: var(--px-bad-soft);
  font-size: var(--px-text-sm);
  line-height: var(--px-line);
  color: var(--px-ink);
}

/*
  THE ACTIONS ARE IN SOURCE ORDER CANCEL THEN CONFIRM, AND ARE NOT REORDERED.

  That plain order already achieves both things that matter. Keyboard focus
  reaches the way out first, because focus follows source order. And the
  confirming button still sits on the right, where a pointer expects it,
  because nothing here reverses anything.

  THIS RULE USED TO SAY row-reverse AND THE COMMENT ABOVE IT WAS SELF
  CONTRADICTORY. Reversing the row moves the confirming button to the LEFT,
  which is not where anyone reaches for it, and it buys nothing, since source
  order alone already decides what the keyboard reaches first. Found by
  measuring the rendered panel rather than by reading the rule, which is the
  only way this kind of fault ever surfaces.

  PUT CANCEL FIRST IN THE MARKUP. This rule cannot do it for you, and a panel
  that lists the destructive button first hands the keyboard straight to it.
*/
.px-confirm-actions {
  display: flex;
  flex-direction: row;
  gap: var(--px-space-2);
}

/* ── Small pieces ──────────────────────────────────────────────────────── */

.px-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--px-space-1);
  padding: 2px var(--px-space-2);
  border-radius: 999px;
  font-size: var(--px-text-xs);
  font-weight: 600;
  line-height: var(--px-line-tight);
  background: var(--px-ground);
  color: var(--px-ink-2);
}

.px-badge-good { background: var(--px-good-soft); color: var(--px-good); }
.px-badge-warn { background: var(--px-warn-soft); color: var(--px-warn); }
.px-badge-bad  { background: var(--px-bad-soft);  color: var(--px-bad); }
.px-badge-info { background: var(--px-accent-soft); color: var(--px-accent); }

/*
  ICONS. Lucide is the family icon set, ratified by Paul on 2026-09-04 and
  recorded in STANDARDS.md section 13. This sizes an inline Lucide symbol and
  keeps it out of the accessibility tree, because an icon beside a word is
  decoration and an icon announced beside its own label is heard twice.

  AN ICON ON ITS OWN IS NOT COVERED BY THIS RULE AND NEEDS A LABEL. If a control
  is an icon and nothing else, give it aria-label and do not use this class to
  excuse the omission.
*/
.px-icon {
  width: 1em;
  height: 1em;
  flex: none;
  stroke-width: 2;
  vertical-align: -0.125em;
}

/* Hides a thing from sight while leaving it available to a screen reader. */
.px-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/*
  A READER WHO HAS ASKED FOR LESS MOVEMENT GETS LESS MOVEMENT. This is one rule
  covering every transition in the file, so no component can forget it.
*/
@media (prefers-reduced-motion: reduce) {
  .px-btn,
  .px-input,
  .px-select,
  .px-textarea {
    transition: none;
  }
}
