/* =============================================================================
   PrivacyWall Design System — Base
   Reset, document defaults, typography classes, icon primitive, a11y helpers.
   Requires: pw-tokens.css
   ============================================================================= */

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

html {
  -webkit-text-size-adjust: 100%;
  scrollbar-color: var(--pw-scrollbar-thumb) transparent;
  scrollbar-width: thin;
}

body {
  margin: 0;
  background: var(--pw-bg-canvas);
  color: var(--pw-fg-primary);
  font-family: var(--pw-font-sans);
  font-size: var(--pw-text-sm-size);
  line-height: var(--pw-text-sm-line);
  font-weight: var(--pw-font-weight-regular);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

h1, h2, h3, h4, h5, h6, p, figure, blockquote, dl, dd { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button, input, select, textarea { font: inherit; color: inherit; }
button { -webkit-tap-highlight-color: transparent; }
img, svg, video, canvas { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }

::-webkit-scrollbar { width: 12px; height: 12px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  min-height: 48px;
  border: 3px solid transparent;
  border-radius: var(--pw-radius-pill);
  background: var(--pw-scrollbar-thumb);
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--pw-scrollbar-thumb-hover); background-clip: content-box; }
::-webkit-scrollbar-button, ::-webkit-scrollbar-corner { display: none; background: transparent; }

::selection { background: var(--pw-color-brand-100); color: var(--pw-color-gray-950); }
html.dark ::selection, [data-pw-theme="dark"] ::selection { background: rgba(76, 144, 254, 0.35); color: var(--pw-color-white); }

/* Keyboard-only focus. Every interactive component opts in via .pw-focusable. */
.pw-focusable:focus-visible,
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--pw-color-brand-600);
  outline-offset: 2px;
  border-radius: var(--pw-radius-xs);
}

/* ---------------------------------------------------------------------------
   TYPOGRAPHY
   -----------------------------------------------------------------------------
   HIERARCHY — the system leans on weight, not size, to separate a title from
   its supporting line. Titles, labels and every piece of interactive chrome sit
   at 500–700; body copy, descriptions and result snippets stay at 400. Raising
   the supporting text alongside the titles would flatten the contrast again,
   which is the thing this is trying to avoid.

     700 bold      display, headings, card/modal/panel titles, buttons, overlines
     600 semibold  labels, chips, tabs, segments, row titles, table headers
     500 medium    menu items, option rows, chosen field values, links
     400 regular   body copy, descriptions, snippets, placeholders, hints
   --------------------------------------------------------------------------- */
.pw-display-2xl { font-size: var(--pw-display-2xl-size); line-height: var(--pw-display-2xl-line); font-weight: var(--pw-font-weight-bold); letter-spacing: var(--pw-tracking-tight); }
.pw-display-xl  { font-size: var(--pw-display-xl-size);  line-height: var(--pw-display-xl-line);  font-weight: var(--pw-font-weight-bold); letter-spacing: var(--pw-tracking-tight); }
.pw-display-lg  { font-size: var(--pw-display-lg-size);  line-height: var(--pw-display-lg-line);  font-weight: var(--pw-font-weight-bold); letter-spacing: var(--pw-tracking-tight); }
.pw-display-md  { font-size: var(--pw-display-md-size);  line-height: var(--pw-display-md-line);  font-weight: var(--pw-font-weight-bold); letter-spacing: var(--pw-tracking-tight); }
.pw-display-sm  { font-size: var(--pw-display-sm-size);  line-height: var(--pw-display-sm-line);  font-weight: var(--pw-font-weight-bold); letter-spacing: var(--pw-tracking-snug); }
.pw-display-xs  { font-size: var(--pw-display-xs-size);  line-height: var(--pw-display-xs-line);  font-weight: var(--pw-font-weight-bold); letter-spacing: var(--pw-tracking-snug); }

/* Headings map onto the text-* steps — in-product structure, not headline copy. */
.pw-heading-lg  { font-size: var(--pw-text-xl-size); line-height: var(--pw-text-xl-line); font-weight: var(--pw-font-weight-bold); letter-spacing: var(--pw-tracking-snug); }
.pw-heading-md  { font-size: var(--pw-text-lg-size); line-height: var(--pw-text-lg-line); font-weight: var(--pw-font-weight-bold); letter-spacing: var(--pw-tracking-snug); }
.pw-heading-sm  { font-size: var(--pw-text-md-size); line-height: var(--pw-text-md-line); font-weight: var(--pw-font-weight-semibold); }
.pw-heading-xs  { font-size: var(--pw-text-sm-size); line-height: var(--pw-text-sm-line); font-weight: var(--pw-font-weight-semibold); }

.pw-body-lg     { font-size: var(--pw-text-md-size); line-height: var(--pw-text-md-line); }
.pw-body        { font-size: var(--pw-text-sm-size); line-height: var(--pw-text-sm-line); }
.pw-body-sm     { font-size: var(--pw-text-xs-size); line-height: var(--pw-text-xs-line); }
.pw-caption     { font-size: var(--pw-text-xs-size); line-height: var(--pw-text-xs-line); color: var(--pw-fg-tertiary); }
.pw-overline {
  font-size: var(--pw-text-xs-size); line-height: var(--pw-text-xs-line);
  font-weight: var(--pw-font-weight-bold);
  letter-spacing: var(--pw-tracking-caps); text-transform: uppercase;
  color: var(--pw-fg-quaternary);
}
.pw-mono { font-family: var(--pw-font-mono); font-size: var(--pw-text-xs-size); }
.pw-italic { font-style: italic; }

.pw-fg-primary    { color: var(--pw-fg-primary); }
.pw-fg-secondary  { color: var(--pw-fg-secondary); }
.pw-fg-tertiary   { color: var(--pw-fg-tertiary); }
.pw-fg-quaternary { color: var(--pw-fg-quaternary); }
.pw-fg-brand      { color: var(--pw-fg-brand); }
.pw-fg-success    { color: var(--pw-fg-success); }
.pw-fg-warning    { color: var(--pw-fg-warning); }
.pw-fg-danger     { color: var(--pw-fg-danger); }

.pw-weight-regular  { font-weight: var(--pw-font-weight-regular); }
.pw-weight-medium   { font-weight: var(--pw-font-weight-medium); }
.pw-weight-semibold { font-weight: var(--pw-font-weight-semibold); }
.pw-weight-bold     { font-weight: var(--pw-font-weight-bold); }

/* Truncation */
/* `hidden` means hidden. Any component that sets `display` silently defeats
   the attribute — the element stays laid out, focusable and in the a11y tree
   while every controller in the system believes it is closed. This is the
   one place `!important` is the correct tool: nothing should ever win
   against it, and a component that needs to override it is wrong.
   Use `.pw-sr-only` for "present but visually hidden". */
[hidden] { display: none !important; }

.pw-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.pw-clamp-1, .pw-clamp-2, .pw-clamp-3, .pw-clamp-4 {
  display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden;
}
.pw-clamp-1 { -webkit-line-clamp: 1; line-clamp: 1; }
.pw-clamp-2 { -webkit-line-clamp: 2; line-clamp: 2; }
.pw-clamp-3 { -webkit-line-clamp: 3; line-clamp: 3; }
.pw-clamp-4 { -webkit-line-clamp: 4; line-clamp: 4; }

/* ---------------------------------------------------------------------------
   LINK
   --------------------------------------------------------------------------- */
.pw-link {
  color: var(--pw-fg-brand);
  text-decoration: none;
  border-radius: var(--pw-radius-xs);
  transition: color var(--pw-duration-fast) var(--pw-ease-out);
}
.pw-link:hover { text-decoration: underline; }
.pw-link--result { color: var(--pw-fg-link); }
.pw-link--result:visited { color: var(--pw-fg-link-visited); }
.pw-link { font-weight: var(--pw-font-weight-medium); }
.pw-link--quiet { color: var(--pw-fg-secondary); }
.pw-link--quiet:hover { color: var(--pw-fg-primary); }

/* ---------------------------------------------------------------------------
   ICON
   Stroke-based, 24-unit viewBox. `--pw-icon-stroke` is in *viewBox units*, so
   the rendered thickness scales with the rendered size — 2 units reads as
   1.67px at 20px and 1.33px at 16px, which is how the source set is drawn.
   Do not compensate per size; that is what makes an icon row look uneven.
   --------------------------------------------------------------------------- */
.pw-icon {
  display: inline-block;
  flex: 0 0 auto;
  width: var(--pw-icon-md);
  height: var(--pw-icon-md);
  color: currentColor;
  stroke-width: var(--pw-icon-stroke);
  vertical-align: middle;
  pointer-events: none;
}
.pw-icon--xs { width: var(--pw-icon-xs); height: var(--pw-icon-xs); }  /* 14 -> 1.17 */
.pw-icon--sm { width: var(--pw-icon-sm); height: var(--pw-icon-sm); }  /* 16 -> 1.33 */
.pw-icon--md { width: var(--pw-icon-md); height: var(--pw-icon-md); }  /* 20 -> 1.67 */
.pw-icon--lg { width: var(--pw-icon-lg); height: var(--pw-icon-lg); }  /* 24 -> 2.00 */
.pw-icon--xl { width: var(--pw-icon-xl); height: var(--pw-icon-xl); }  /* 28 -> 2.33 */
.pw-icon--spin { animation: pw-spin 900ms linear infinite; }

@keyframes pw-spin { to { transform: rotate(360deg); } }

/* ---------------------------------------------------------------------------
   DIVIDER
   --------------------------------------------------------------------------- */
.pw-divider { border: 0; height: 1px; background: var(--pw-border-subtle); margin: 0; }
.pw-divider--strong { background: var(--pw-border-default); }
.pw-divider--vertical { width: 1px; height: auto; align-self: stretch; }
.pw-divider--labelled {
  display: flex; align-items: center; gap: var(--pw-space-6);
  height: auto; background: none;
  font-size: var(--pw-text-xs-size); color: var(--pw-fg-quaternary);
}
.pw-divider--labelled::before,
.pw-divider--labelled::after { content: ""; flex: 1; height: 1px; background: var(--pw-border-subtle); }

/* ---------------------------------------------------------------------------
   KEYBOARD KEY
   --------------------------------------------------------------------------- */
.pw-kbd {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 var(--pw-space-2);
  border: 1px solid var(--pw-border-default);
  border-bottom-width: 2px;
  border-radius: var(--pw-radius-sm);
  background: var(--pw-bg-subtle);
  color: var(--pw-fg-tertiary);
  font-family: var(--pw-font-mono);
  font-size: var(--pw-text-xs-size);
  line-height: 1;
}

/* ---------------------------------------------------------------------------
   ACCESSIBILITY HELPERS
   --------------------------------------------------------------------------- */
/* Keeps what it wraps on one line: the last word of a sentence and the citation after it, so a badge never starts
   the next line on its own. */
.pw-nowrap { white-space: nowrap; }
.pw-sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.pw-skip-link {
  position: absolute; left: var(--pw-space-4); top: var(--pw-space-4);
  z-index: var(--pw-z-tooltip);
  padding: var(--pw-space-3) var(--pw-space-6);
  border-radius: var(--pw-radius-md);
  background: var(--pw-bg-surface); color: var(--pw-fg-primary);
  box-shadow: var(--pw-shadow-lg);
  transform: translateY(-200%);
  transition: transform var(--pw-duration-fast) var(--pw-ease-out);
}
.pw-skip-link:focus-visible { transform: translateY(0); }

/* ---------------------------------------------------------------------------
   REDUCED MOTION
   Movement is removed; colour and opacity transitions are kept so state stays
   legible without animation.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------------------
   ONE OF A PAIR  —  for artwork that cannot serve both themes
   A token changes colour; an SVG file does not. Where a mark is a FILE rather
   than a sprite symbol — the AI lockup, whose wordmark is solid and whose
   glyph is a gradient — the only way to give it a dark-mode twin is to ship
   two and show one. Declared in all three blocks for the same reason the
   tokens are: an explicit choice wins, and the system preference is the
   fallback rather than the rule.

   `revert` and not `block`: the pair might be images, spans or anything else,
   and this utility has no business deciding what display type they are.

   `!important`, for the same reason `[hidden]` above carries it. This is the
   second of the three cases in the system where nothing should ever win against
   it -- the third is the collapsed sidebar hiding this very lockup, which needs
   an `!important` of its own precisely because this one is here. The reason: a component that gives
   the mark a `display` -- and the sidebar's lockup does -- loads after this
   file and would otherwise show both halves of the pair at once, which is
   exactly the bug this utility exists to prevent.
   --------------------------------------------------------------------------- */
.only-dark { display: none !important; }
html.dark .only-dark, [data-pw-theme="dark"] .only-dark { display: revert !important; }
html.dark .only-light, [data-pw-theme="dark"] .only-light { display: none !important; }
@media (prefers-color-scheme: dark) {
  :root:not(.light):not([data-pw-theme="light"]) .only-dark { display: revert !important; }
  :root:not(.light):not([data-pw-theme="light"]) .only-light { display: none !important; }
}
