/* =============================================================================
   UORA base stylesheet
   web/assets/css/base.css — load after tokens.css and before any page stylesheet.

     <link rel="stylesheet" href="/assets/css/tokens.css">
     <link rel="stylesheet" href="/assets/css/base.css">
     <link rel="stylesheet" href="/assets/css/print.css" media="print">

   Reset, typography, layout primitives and the component set the product needs.
   Class names follow the PLM convention: terse two-letter utilities for
   in-product type (.pt .st .ct .fl), .btn with a one-letter variant (.bp .bg
   .bh .bd .bs) and a .bsm size modifier. No BEM, no framework.

   Accessibility commitments made here, which a page must not undo:
     - Every interactive element has a visible focus ring in the accent colour.
       :focus-visible is used so a mouse click does not paint a ring, but the
       ring is never removed outright.
     - Text meets 4.5:1 against the surface it sits on.
     - Motion respects prefers-reduced-motion (durations are neutralised in
       tokens.css and animations are stopped at the bottom of this file).
     - Nothing communicates state by colour alone: chips carry a word, form
       errors carry text and aria-invalid, countdowns carry the absolute time.
   ============================================================================= */

/* -----------------------------------------------------------------------------
   Fonts

   Inter and Inter Tight are self-hosted. This is mandatory, not a preference:
   Puppeteer renders awards and receipts offline and must not depend on a Google
   Fonts fetch, and the same token file is reused by the email and PDF templates.
   Place the variable files from rsms.me/inter at the paths below. If they are
   absent the stack falls back to the system sans, which is a legible degradation
   rather than a broken page.
   -------------------------------------------------------------------------- */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('../fonts/InterVariable.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 900;
  font-display: swap;
  src: url('../fonts/InterVariable-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF,
    U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020,
    U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* Arabic UI face. The brand specifies Noto Sans Arabic for interface Arabic and
   Noto Naskh Arabic for legal Arabic; the Naskh face is embedded separately by
   lib/pdf.js for documents and is deliberately NOT loaded here. */
@font-face {
  font-family: 'Noto Sans Arabic';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../fonts/NotoSansArabic-400.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0898-08E1,
    U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FEFF;
}

@font-face {
  font-family: 'Noto Sans Arabic';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('../fonts/NotoSansArabic-600.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0898-08E1,
    U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FEFF;
}

@font-face {
  font-family: 'Noto Sans Arabic';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../fonts/NotoSansArabic-700.woff2') format('woff2');
  unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0898-08E1,
    U+08E3-08FF, U+200C-200E, U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FEFF;
}

/* ============================================================== reset ===== */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body,
h1, h2, h3, h4, h5, h6,
p, figure, blockquote, dl, dd, ol, ul, fieldset, legend {
  margin: 0;
  padding: 0;
}

ol, ul {
  list-style: none;
}

body {
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  font-weight: var(--fw-body);
  line-height: var(--lh-body);
  letter-spacing: var(--tr-body);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
}

img, svg, video, canvas {
  display: block;
  max-width: 100%;
  height: auto;
}

button, input, select, textarea {
  font: inherit;
  letter-spacing: inherit;
  color: inherit;
}

button {
  background: none;
  border: 0;
  cursor: pointer;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
}

hr {
  height: 0;
  border: 0;
  border-top: var(--hairline) solid var(--border);
  margin: var(--s-6) 0;
}

/* There is no italic in the system: Inter Italic is not loaded, so a browser
   would synthesise an oblique. Legal prose is full of <em> and <cite> by habit;
   these are reset and emphasis is carried by weight instead. */
em, i, cite, dfn, address, var {
  font-style: normal;
}

em, cite, dfn {
  font-weight: var(--fw-strong);
}

blockquote {
  border-inline-start: 2px solid var(--border2);
  padding-inline-start: var(--s-4);
  color: var(--text2);
}

::selection {
  background: var(--accent-soft);
  color: var(--text);
}

::placeholder {
  color: var(--text3);
  opacity: 1;
}

/* One focus treatment for everything. Never remove it; if a control needs a
   different shape, restyle the ring, do not switch it off. */
:focus-visible {
  outline: var(--focus-outline-width) solid var(--accent);
  outline-offset: var(--focus-outline-offset);
  border-radius: var(--r-xs);
}

:focus:not(:focus-visible) {
  outline: none;
}

/* ========================================================= typography ===== */

h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: var(--lh-heading);
  color: var(--text);
}

/* p17 assigns a line height per level as well as a size and a weight. h1 is
   tighter than h2, and both are tighter than body, which is what produces the
   "large hierarchy" the system asks for. */
h1 { font-size: var(--fs-h1); font-weight: var(--fw-title); letter-spacing: var(--tr-title); line-height: var(--lh-tight); }
h2 { font-size: var(--fs-h2); font-weight: var(--fw-title); letter-spacing: var(--tr-card); line-height: var(--lh-heading); }
h3 { font-size: var(--fs-h3); font-weight: var(--fw-strong); letter-spacing: var(--tr-card); }
h4 { font-size: var(--fs-body-sm); font-weight: var(--fw-strong); letter-spacing: var(--tr-card); }

a {
  color: var(--accent);
  text-decoration: none;
  text-underline-offset: 3px;
  transition: color var(--t-fast) var(--ease);
}

a:hover {
  color: var(--accent-deep);
  text-decoration: underline;
}

/* Prose links inside long-form legal text are underlined by default: in a rules
   page the reader must be able to see what is a reference without hovering. */
.prose a,
a.link {
  text-decoration: underline;
}

/* Page title, in-product. */
.pt {
  font-family: var(--font-display);
  font-size: var(--fs-h1);
  font-weight: var(--fw-title);
  letter-spacing: var(--tr-title);
  line-height: var(--lh-heading);
}

/* Section title. */
.st {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--fw-strong);
  letter-spacing: var(--tr-title);
  line-height: var(--lh-heading);
}

/* Card title. */
.ct {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-strong);
  letter-spacing: var(--tr-card);
  line-height: var(--lh-heading);
}

/* Uppercase micro-label. The one place tracking is positive. */
/* Uppercase metadata labels. p13 reserves Aurum for "the mark, primary actions,
   key numbers, active states, verification details and deliberate accents" —
   a metadata label is exactly such an accent, and p18 pairs uppercase with
   metadata ("CASE UORA-2026-000123", "AWARD PENDING", "DUBAI TIME"). The whole
   page had been rendering these in Muted, which is why an audit of the live
   page found Aurum on 0.27% of it against a system built around 70/20/10. */
.fl,
.eyebrow {
  display: block;
  font-size: var(--fs-micro);
  font-weight: var(--fw-ui);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  color: var(--accent);
  line-height: var(--lh-ui);
}

.eyebrow {
  letter-spacing: var(--tr-eyebrow);
  /* Muted, not Aurum 700. #C88737 is a deep bronze and at eyebrow size on
     Obsidian it reads as orange, which is not what p13 means by "one premium
     accent". The gold stays on the data labels (.fl) and the primary action. */
  color: var(--text2);
}

.lead {
  font-size: var(--fs-lead);
  line-height: var(--lh-prose);
  color: var(--text2);
}

.muted { color: var(--text2); }
.fine  { font-size: var(--fs-caption); color: var(--text3); }
.small { font-size: var(--fs-small); }
.strong { font-weight: var(--fw-strong); }

.mono {
  font-family: var(--font-mono);
  font-size: 0.92em;
  letter-spacing: 0;
}

/* Every figure a reader compares down a column: money, case numbers, deadlines,
   SHA-256 digests, exhibit numbers. This is the single most valuable typographic
   detail in a table-heavy arbitration product. */
.num,
.money,
.tabular,
td.num,
th.num {
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tr-num);
}

.money {
  white-space: nowrap;
}

.hero-num {
  font-family: var(--font-display);
  font-size: var(--fs-num-hero);
  font-weight: var(--fw-title);
  letter-spacing: var(--tr-display);
  font-variant-numeric: tabular-nums;
  color: var(--accent);
}

.prose {
  max-width: 68ch;
  line-height: var(--lh-prose);
  color: var(--text2);
}

.prose h2,
.prose h3 {
  color: var(--text);
  margin-block: var(--s-7) var(--s-3);
}

.prose p,
.prose ul,
.prose ol {
  margin-block: 0 var(--s-4);
}

.prose ul,
.prose ol {
  padding-inline-start: var(--s-5);
}

.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
.prose li { margin-block-end: var(--s-2); }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Keyboard escape hatch out of the header on every page. */
.skip-link {
  position: absolute;
  inset-inline-start: var(--s-4);
  top: calc(var(--s-2) * -8);
  z-index: var(--z-toast);
  padding: var(--s-2) var(--s-4);
  background: var(--accent-fill);
  color: var(--text-on-accent);
  border-radius: var(--r-sm);
  font-weight: var(--fw-ui);
  transition: top var(--t) var(--ease);
}

.skip-link:focus-visible {
  top: var(--s-2);
}

/* ==================================================== layout primitives === */

.shell {
  width: 100%;
  max-width: var(--shell-max);
  margin-inline: auto;
  padding-inline: var(--shell-pad);
}

.shell--wide   { max-width: var(--shell-wide); }
.shell--narrow { max-width: var(--shell-narrow); }

.page {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.page__main {
  flex: 1 1 auto;
  padding-block: var(--s-7) var(--s-10);
}

/* Site header — sits one step up the ramp from the canvas. */
.site-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  min-height: var(--header-h);
  background: var(--bg-1);
  border-block-end: var(--hairline) solid var(--border);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  min-height: var(--header-h);
}

.site-header__brand {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex: 0 0 auto;
}

.site-header__brand img,
.site-header__brand svg {
  height: 26px;
  width: auto;
}

.site-nav {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  flex: 1 1 auto;
  flex-wrap: wrap;
}

.site-nav a {
  font-size: var(--fs-small);
  font-weight: var(--fw-label);
  letter-spacing: var(--tr-ui);
  color: var(--text2);
}

.site-nav a:hover,
.site-nav a[aria-current="page"] {
  color: var(--accent);
}

.site-header__actions {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex: 0 0 auto;
}

/* The wordmark. There is no logotype file and there is not going to be one: the
   mark is the word, set in the display face. As text it inherits the token
   colours, scales with the reader's font settings, needs no alt text and costs
   no request. */
.wordmark {
  font-family: var(--font-display);
  font-size: 19px;
  font-weight: var(--fw-title);
  letter-spacing: var(--tr-title);
  line-height: 1;
  color: var(--text);
}

.wordmark:hover,
.wordmark:focus-visible {
  color: var(--accent);
  text-decoration: none;
}

/* Menu button for the collapsed navigation. Hidden — not merely invisible —
   above the breakpoint, so it never appears in the tab order on a wide viewport
   where the nav itself is already the control. */
.site-header__toggle {
  /* The selector must out-specify `.btn { display: inline-flex }`, which is
     declared later in this file at equal specificity and was therefore winning.
     The Menu button was visible and focusable at EVERY width on every public
     page — a dead control sitting in the tab order beside a nav that was
     already showing. Doubling the class is enough and needs no !important. */
  display: none;
}

.site-header__toggle.site-header__toggle {
  display: none;
}

/* Collapsed navigation, under 720px. site.js toggles .is-nav-open on the header
   and keeps aria-expanded on the button in step. The nav is display:none when
   closed, so it leaves the tab order and the accessibility tree together; there
   is no aria-hidden to fall out of sync. */
@media (max-width: 720px) {
  .site-header__inner {
    flex-wrap: wrap;
    gap: var(--s-3);
  }

  .site-header__actions {
    order: 2;
    margin-inline-start: auto;
  }

  .site-header__toggle.site-header__toggle {
    display: inline-flex;
    order: 3;
  }

  .site-nav {
    order: 4;
    display: none;
    flex: 1 0 100%;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding-block-end: var(--s-3);
    border-block-start: var(--hairline) solid var(--border);
  }

  .site-header.is-nav-open .site-nav {
    display: flex;
  }

  .site-nav a {
    padding-block: var(--s-3);
    font-size: var(--fs-body-sm);
  }

  .site-nav a + a {
    border-block-start: var(--hairline) solid var(--border);
  }
}

.site-footer {
  border-block-start: var(--hairline) solid var(--border);
  background: var(--bg-1);
  padding-block: var(--s-8);
  color: var(--text3);
  font-size: var(--fs-caption);
}

.site-footer a { color: var(--text2); }
.site-footer a:hover { color: var(--text); }

.site-footer__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--s-6);
}

/* The mandatory legal notice. It is the one piece of footer text a reader may
   actually have to read, so it is set a step larger and a step brighter than the
   rest of the footer and given a prose measure. */
.site-footer__notice {
  max-width: 92ch;
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--text2);
}

.site-footer__operator,
.site-footer__version {
  max-width: 92ch;
}

.site-footer__links {
  gap: var(--s-2) var(--s-5);
}

.site-footer__links a {
  font-weight: var(--fw-label);
}

.site-footer__links a[aria-current="page"] {
  color: var(--accent);
}

/* The operator lockup. PLM is the legal person behind the platform and must be
   identifiable on every surface, so this is a component, not page copy. */
.operator-lockup {
  display: block;
  margin-block-start: var(--s-6);
  padding-block-start: var(--s-4);
  border-block-start: var(--hairline) solid var(--border);
  font-size: var(--fs-caption);
  color: var(--text3);
}

/* Vertical rhythm helper: children are spaced, nothing else changes. */
.stack {
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}

.stack--tight { gap: var(--s-2); }
.stack--loose { gap: var(--s-7); }

/* Horizontal row that wraps. */
.row,
.cluster {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
}

.row--between { justify-content: space-between; }
.row--end     { justify-content: flex-end; }
.row--top     { align-items: flex-start; }
.row--nowrap  { flex-wrap: nowrap; }

.grid {
  display: grid;
  gap: var(--s-5);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}

.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

/* Case pages: main column plus a rail of action cards and deadlines. */
.split {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: minmax(0, 1fr) 340px;
  align-items: start;
}

.split--rail-start {
  grid-template-columns: 300px minmax(0, 1fr);
}

@media (max-width: 960px) {
  .split,
  .split--rail-start,
  .grid--2,
  .grid--3,
  .grid--4 {
    grid-template-columns: minmax(0, 1fr);
  }
}

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-5);
  flex-wrap: wrap;
  margin-block-end: var(--s-6);
}

.page-head__meta {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-block-start: var(--s-2);
  font-size: var(--fs-small);
  color: var(--text2);
}

.divider {
  height: var(--hairline);
  background: var(--border);
  border: 0;
  margin-block: var(--s-5);
}

/* ============================================================ buttons ===== */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  /* p21: "48-52 px controls". The height is explicit rather than a product of
     vertical padding, so a button keeps its size whatever the label does. */
  min-height: var(--control-h);
  padding: var(--btn-pad);
  border: var(--hairline) solid transparent;
  border-radius: var(--r-btn);
  font-family: var(--font-sans);
  font-size: var(--fs-btn);
  font-weight: var(--fw-ui);
  letter-spacing: var(--tr-body);
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none;
  transition:
    background-color var(--t-fast) var(--ease),
    border-color var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease),
    transform var(--t-fast) var(--ease);
}

.btn:hover { text-decoration: none; }
.btn:active { transform: translateY(1px); }

.btn[disabled],
.btn[aria-disabled="true"],
.btn.is-busy {
  cursor: not-allowed;
  opacity: .55;
  transform: none;
  pointer-events: none;
}

.btn svg {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
}

/* Small modifier. */
.btn.bsm {
  min-height: var(--control-h-sm);
  padding: var(--btn-pad-sm);
  font-size: var(--fs-btn-sm);
}

.btn.bsm svg { width: 12px; height: 12px; }

.btn--block { width: 100%; }

/* Primary. Exactly one per screen, for the single most important action. A
   dispute workflow will tempt you to break this; use .bg for the rest. */
.btn.bp {
  background: var(--accent-fill);
  color: var(--text-on-accent);
  border-color: var(--accent-fill);
}

.btn.bp:hover {
  background: var(--accent-deep);
  border-color: var(--accent-deep);
}

.btn.bp:focus-visible {
  box-shadow: var(--focus-ring);
}

/* Reserved for the hero call to action on the public site. */
.btn.bp.btn--hero {
  box-shadow: var(--shadow-accent);
}

/* Secondary. Multiple per screen. */
.btn.bg {
  background: rgba(255, 255, 255, .05);
  border-color: var(--border2);
  color: var(--accent);
}

.btn.bg:hover {
  background: var(--bg-3);
  border-color: var(--border3);
}

/* Ghost — tertiary actions in crowded layouts (table row actions, toolbars). */
.btn.bh {
  background: transparent;
  border-color: transparent;
  color: var(--text2);
}

.btn.bh:hover {
  background: var(--bg-3);
  color: var(--text);
}

/* Destructive: withdraw, delete a draft, cancel a payment. */
.btn.bd {
  background: var(--danger-soft);
  border-color: var(--danger-line);
  color: var(--danger);
}

.btn.bd:hover {
  background: rgba(242, 107, 107, .18);
  border-color: var(--danger);
}

/* Explicit positive confirmation only ("Confirm the review has been removed").
   Never a generic call to action. */
.btn.bs {
  background: var(--ok-soft);
  border-color: var(--ok-line);
  color: var(--ok);
}

.btn.bs:hover {
  background: rgba(26, 182, 128, .24);
  border-color: var(--ok);
}

.btn-group {
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
}

/* A link that behaves as a tertiary action inside prose or a table cell. */
.link-action {
  font-size: var(--fs-small);
  font-weight: var(--fw-ui);
  color: var(--accent);
}

/* ============================================================== forms ===== */

.form {
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

.field--inline {
  flex-direction: row;
  align-items: center;
  gap: var(--s-3);
}

.field__label,
label.fl {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  color: var(--text2);
}

.field__required {
  color: var(--accent);
  font-weight: var(--fw-strong);
}

.field__hint {
  font-size: var(--fs-caption);
  color: var(--text3);
  line-height: var(--lh-ui);
}

.input,
.select,
.textarea,
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="number"],
input[type="password"],
input[type="date"],
input[type="datetime-local"],
input[type="search"],
select,
textarea {
  width: 100%;
  min-height: var(--control-h);
  padding: var(--s-2) var(--s-3);
  background: var(--bg-2);
  color: var(--text);
  border: var(--hairline) solid var(--border);
  border-radius: var(--r-input);
  font-size: var(--fs-body-sm);
  line-height: var(--lh-ui);
  transition:
    border-color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease),
    background-color var(--t-fast) var(--ease);
}

/* No Material underline, no floating label: the label sits above the control. */
.input:hover,
select:hover,
textarea:hover,
input:hover {
  border-color: var(--border2);
}

.input:focus,
.select:focus,
.textarea:focus,
input:focus,
select:focus,
textarea:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: var(--focus-ring);
}

/* Keyboard users still get the outline; the glow alone is not enough of a cue. */
.input:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible {
  outline: var(--focus-outline-width) solid var(--accent);
  outline-offset: 1px;
}

textarea,
.textarea {
  min-height: 120px;
  padding: var(--s-3);
  resize: vertical;
  line-height: var(--lh-body);
}

select,
.select {
  appearance: none;
  padding-inline-end: var(--s-7);
  background-image:
    linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position:
    calc(100% - 18px) calc(50% + 2px),
    calc(100% - 13px) calc(50% + 2px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  cursor: pointer;
}

input[disabled],
select[disabled],
textarea[disabled],
.input[disabled] {
  background: var(--bg-1);
  color: var(--text3-quiet);
  cursor: not-allowed;
}

input[readonly],
textarea[readonly] {
  background: var(--bg-1);
  color: var(--text2);
}

/* Server-side validation errors are rendered by ui.js applyFieldErrors(), which
   sets aria-invalid and describes the control with the message element. The
   colour is a reinforcement, never the only signal. */
[aria-invalid="true"],
.field.is-invalid .input,
.field.is-invalid input,
.field.is-invalid select,
.field.is-invalid textarea {
  border-color: var(--danger);
}

[aria-invalid="true"]:focus,
.field.is-invalid .input:focus,
.field.is-invalid input:focus,
.field.is-invalid textarea:focus {
  box-shadow: 0 0 0 3px var(--danger-soft);
}

.field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  font-size: var(--fs-caption);
  line-height: var(--lh-ui);
  color: var(--danger);
}

.field__error[hidden] { display: none; }

.field__error svg {
  width: 13px;
  height: 13px;
  flex: 0 0 auto;
  margin-block-start: 1px;
}

/* Form-level error summary, placed above the form and focused on failure so a
   screen-reader user hears why the submission was rejected. */
.form-error {
  display: flex;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--danger-soft);
  border: var(--hairline) solid var(--danger-line);
  border-radius: var(--r-sm);
  color: var(--danger);
  font-size: var(--fs-small);
}

.form-error[hidden] { display: none; }

.form-error ul {
  margin-block-start: var(--s-2);
  padding-inline-start: var(--s-4);
  list-style: disc;
}

.form-actions {
  display: flex;
  gap: var(--s-3);
  align-items: center;
  flex-wrap: wrap;
  padding-block-start: var(--s-2);
}

.form-actions--split {
  justify-content: space-between;
}

/* Checkbox and radio. The declarations page of the claim form is a long list of
   these, so the hit area is the whole row. */
.check,
.radio {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-3);
  border: var(--hairline) solid var(--border);
  border-radius: var(--r-input);
  background: var(--bg-2);
  cursor: pointer;
  font-size: var(--fs-body-sm);
  line-height: var(--lh-ui);
  transition: border-color var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}

.check:hover,
.radio:hover {
  border-color: var(--border2);
  background: var(--bg-3);
}

.check input,
.radio input {
  width: 16px;
  height: 16px;
  min-height: 0;
  margin: 2px 0 0;
  padding: 0;
  flex: 0 0 auto;
  accent-color: var(--accent);
  cursor: pointer;
}

.check--bare,
.radio--bare {
  padding: 0;
  border: 0;
  background: none;
  align-items: center;
}

.check--bare:hover,
.radio--bare:hover {
  background: none;
}

.check__text { display: block; }
.check__note {
  display: block;
  margin-block-start: var(--s-1);
  font-size: var(--fs-caption);
  color: var(--text3);
}

fieldset {
  border: 0;
  padding: 0;
  margin: 0;
}

legend {
  padding: 0;
  margin-block-end: var(--s-2);
}

/* ============================================================== cards ===== */

.card {
  background: linear-gradient(180deg, var(--bg-2), var(--bg-1));
  border: var(--hairline) solid var(--border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  padding: var(--s-5);
  transition: border-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}

.card--interactive:hover {
  border-color: var(--border2);
  box-shadow: var(--shadow);
}

.card--compact {
  border-radius: var(--r);
  padding: var(--s-4);
}

/* Cards never carry state in their border or background: stacked states become
   unreadable. State goes in a chip. This modifier only raises the emphasis of
   the single card holding the action the user must take next. */
.card--action {
  border-color: var(--accent-line);
}

.card__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  margin-block-end: var(--s-4);
}

.card__title {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-strong);
  letter-spacing: var(--tr-card);
}

.card__body > * + * {
  margin-block-start: var(--s-3);
}

.card__foot {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-block-start: var(--s-5);
  padding-block-start: var(--s-4);
  border-block-start: var(--hairline) solid var(--border);
}

/* Label/value pairs: parties, contract reference, review platform. */
.kv {
  display: grid;
  grid-template-columns: minmax(120px, 34%) minmax(0, 1fr);
  gap: var(--s-2) var(--s-4);
  font-size: var(--fs-body-sm);
}

.kv dt {
  color: var(--text2);
  font-size: var(--fs-caption);
  font-weight: var(--fw-ui);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  padding-block-start: 2px;
}

.kv dd {
  margin: 0;
  color: var(--text);
}

@media (max-width: 560px) {
  .kv { grid-template-columns: minmax(0, 1fr); gap: var(--s-1) 0; }
  .kv dd { margin-block-end: var(--s-3); }
}

/* ============================================================= tables =====
   The app pages are dense and table-first, like the PLM admin console. */

.table-wrap {
  width: 100%;
  overflow-x: auto;
  border: var(--hairline) solid var(--border);
  border-radius: var(--r);
  background: var(--bg-1);
}

.table {
  width: 100%;
  font-size: var(--fs-small);
  line-height: var(--lh-ui);
}

.table caption {
  padding: var(--s-3) var(--s-4);
  text-align: start;
  color: var(--text2);
  font-size: var(--fs-caption);
}

.table th,
.table td {
  padding: var(--s-3) var(--s-4);
  text-align: start;
  vertical-align: top;
  border-block-end: var(--hairline) solid var(--border);
}

.table thead th {
  position: sticky;
  top: 0;
  z-index: var(--z-raised);
  background: var(--bg-2);
  color: var(--text2);
  font-size: var(--fs-micro);
  font-weight: var(--fw-ui);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  white-space: nowrap;
}

.table tbody tr:last-child th,
.table tbody tr:last-child td {
  border-block-end: 0;
}

.table tbody tr {
  transition: background-color var(--t-fast) var(--ease);
}

.table tbody tr:hover {
  background: var(--bg-2);
}

.table--dense th,
.table--dense td {
  padding: var(--s-2) var(--s-3);
}

.table--fixed { table-layout: fixed; }

.table td.num,
.table th.num,
.table .money {
  text-align: end;
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tr-num);
  white-space: nowrap;
}

.table td.actions {
  text-align: end;
  white-space: nowrap;
}

/* Sortable column headers announce their state through aria-sort. */
.table th[aria-sort] button {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
}

.table th[aria-sort="ascending"] button::after  { content: '\2191'; }
.table th[aria-sort="descending"] button::after { content: '\2193'; }

.table-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-block-end: var(--s-3);
}

/* =============================================================== chips ====
   State is a WORD in a tinted pill, optionally with a line icon. Tinted, never
   filled; no drop shadow; never a coloured card border. */

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  padding: 3px 10px;
  border: var(--hairline) solid transparent;
  border-radius: var(--r-pill);
  background: var(--neutral-soft);
  color: var(--text2);
  font-size: var(--fs-caption);
  font-weight: var(--fw-ui);
  letter-spacing: var(--tr-ui);
  line-height: 1.5;
  white-space: nowrap;
  vertical-align: middle;
}

.chip svg {
  width: 12px;
  height: 12px;
  flex: 0 0 auto;
}

.chip--neutral { background: var(--neutral-soft); border-color: var(--neutral-line); color: var(--text2); }
.chip--accent  { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }
.chip--ok      { background: var(--ok-soft);     border-color: var(--ok-line);     color: var(--ok); }
.chip--warn    { background: var(--warn-soft);   border-color: var(--warn-line);   color: var(--warn); }
.chip--danger  { background: var(--danger-soft); border-color: var(--danger-line); color: var(--danger); }

/* Square-ish badge for inline document and exhibit references. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  padding: 2px 7px;
  border-radius: var(--r-xs);
  background: var(--bg-3);
  border: var(--hairline) solid var(--border2);
  color: var(--text2);
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  letter-spacing: 0;
}

/* "Action required" marker on a dashboard row. */
.dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: var(--r-pill);
  background: var(--accent);
  flex: 0 0 auto;
}

.dot--warn   { background: var(--warn); }
.dot--danger { background: var(--danger); }
.dot--ok     { background: var(--ok); }
.dot--muted  { background: var(--text3); }

/* ============================================================ timeline ====
   The case page timeline: every event and every document, newest last, each with
   its Dubai-time stamp. */

.timeline {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-5);
  padding-inline-start: var(--s-6);
}

.timeline::before {
  content: '';
  position: absolute;
  inset-block: 6px 6px;
  inset-inline-start: 5px;
  width: var(--hairline);
  background: var(--border2);
}

.timeline__item {
  position: relative;
}

.timeline__item::before {
  content: '';
  position: absolute;
  inset-inline-start: calc(var(--s-6) * -1 + 1px);
  top: 6px;
  width: 9px;
  height: 9px;
  border-radius: var(--r-pill);
  background: var(--bg-3);
  border: 2px solid var(--border3);
}

.timeline__item--done::before   { background: var(--ok); border-color: var(--ok); }
.timeline__item--now::before    { background: var(--accent); border-color: var(--accent); }
.timeline__item--failed::before { background: var(--danger); border-color: var(--danger); }

.timeline__when {
  display: block;
  font-size: var(--fs-caption);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tr-num);
  color: var(--text3);
}

.timeline__title {
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-strong);
  letter-spacing: var(--tr-card);
  color: var(--text);
}

.timeline__body {
  margin-block-start: var(--s-1);
  font-size: var(--fs-small);
  color: var(--text2);
}

.timeline__attachments {
  display: flex;
  gap: var(--s-2);
  flex-wrap: wrap;
  margin-block-start: var(--s-2);
}

/* ============================================================ countdown ===
   Rendered and ticked by ui.js countdown(). The absolute deadline is always
   present in the markup as well as the relative one, because a document may cite
   the absolute time and the two must agree. */

.countdown {
  display: inline-flex;
  align-items: baseline;
  gap: var(--s-2);
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tr-num);
}

.countdown__value {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--fw-title);
  letter-spacing: var(--tr-title);
  color: var(--text);
}

.countdown__absolute {
  font-size: var(--fs-caption);
  color: var(--text3);
}

.countdown--soon .countdown__value    { color: var(--warn); }
.countdown--overdue .countdown__value { color: var(--danger); }

.countdown-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
}

.countdown-card__label {
  font-size: var(--fs-micro);
  font-weight: var(--fw-ui);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  color: var(--text2);
}

/* ============================================================= dropzone ===
   Evidence upload. Keyboard-operable: the label wraps a real file input, so
   Space and Enter open the picker without any script. */

.dropzone {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 148px;
  padding: var(--s-6);
  text-align: center;
  background: var(--bg-2);
  border: 1px dashed var(--border2);
  border-radius: var(--r);
  color: var(--text2);
  cursor: pointer;
  transition: border-color var(--t) var(--ease), background-color var(--t) var(--ease);
}

.dropzone:hover {
  border-color: var(--border3);
  background: var(--bg-3);
}

.dropzone.is-over {
  border-color: var(--accent);
  border-style: solid;
  background: var(--accent-soft);
  color: var(--text);
}

.dropzone.is-invalid {
  border-color: var(--danger);
  background: var(--danger-soft);
}

.dropzone:focus-within {
  border-color: var(--accent);
  box-shadow: var(--focus-ring);
}

.dropzone input[type="file"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-height: 0;
  padding: 0;
  opacity: 0;
  cursor: pointer;
}

.dropzone__icon svg {
  width: 32px;
  height: 32px;
  color: var(--text3);
}

.dropzone__title {
  font-size: var(--fs-body-sm);
  font-weight: var(--fw-ui);
  color: var(--text);
}

.dropzone__hint {
  font-size: var(--fs-caption);
  color: var(--text3);
}

.filelist {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  margin-block-start: var(--s-3);
}

.filelist__item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) var(--s-3);
  background: var(--bg-2);
  border: var(--hairline) solid var(--border);
  border-radius: var(--r-sm);
  font-size: var(--fs-small);
}

.filelist__name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.filelist__meta {
  flex: 0 0 auto;
  font-size: var(--fs-caption);
  color: var(--text3);
  font-variant-numeric: tabular-nums;
}

/* Determinate upload progress. */
.progress {
  height: 3px;
  width: 100%;
  border-radius: var(--r-pill);
  background: var(--bg-4);
  overflow: hidden;
}

.progress__bar {
  height: 100%;
  width: 0;
  background: var(--accent);
  transition: width var(--t) var(--ease);
}

/* =============================================================== modal ====
   Works with <dialog> and with a plain div[role="dialog"] fallback. */

.modal,
dialog.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-5);
  width: 100%;
  max-width: none;
  max-height: none;
  border: 0;
  background: rgba(5, 5, 5, .72);
  overflow-y: auto;
}

dialog.modal::backdrop {
  background: rgba(5, 5, 5, .72);
}

.modal[hidden] { display: none; }

.modal__panel {
  width: 100%;
  max-width: 520px;
  max-height: calc(100vh - var(--s-9));
  overflow-y: auto;
  padding: var(--s-6);
  background: linear-gradient(180deg, var(--bg-2), var(--bg-1));
  border: var(--hairline) solid var(--border2);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
  animation: uora-modal-in var(--t-slow) var(--ease-out);
}

.modal__panel--wide { max-width: 840px; }

.modal__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  margin-block-end: var(--s-4);
}

.modal__title {
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: var(--fw-title);
  letter-spacing: var(--tr-title);
}

.modal__body {
  font-size: var(--fs-body-sm);
  color: var(--text2);
  line-height: var(--lh-body);
}

.modal__foot {
  display: flex;
  justify-content: flex-end;
  gap: var(--s-3);
  flex-wrap: wrap;
  margin-block-start: var(--s-6);
}

.modal__close {
  flex: 0 0 auto;
  padding: var(--s-1);
  border-radius: var(--r-sm);
  color: var(--text3);
  line-height: 0;
}

.modal__close:hover { color: var(--text); }
.modal__close svg { width: 18px; height: 18px; }

@keyframes uora-modal-in {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* Body scroll lock while a modal is open. */
body.is-modal-open {
  overflow: hidden;
}

/* =============================================================== toast ====
   Transient confirmations. Never used for anything a party must act on: an
   action with legal effect gets a document, an email and a timeline entry. */

.toasts {
  position: fixed;
  inset-block-end: var(--s-5);
  inset-inline-end: var(--s-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  width: min(360px, calc(100vw - var(--s-8)));
  pointer-events: none;
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: var(--bg-2);
  border: var(--hairline) solid var(--border2);
  border-radius: var(--r);
  box-shadow: var(--shadow);
  color: var(--text);
  font-size: var(--fs-small);
  line-height: var(--lh-ui);
  pointer-events: auto;
  animation: uora-toast-in var(--t-slow) var(--ease-out);
}

.toast.is-leaving {
  animation: uora-toast-out var(--t) var(--ease) forwards;
}

.toast svg {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  margin-block-start: 1px;
}

.toast--ok      { border-color: var(--ok-line); }
.toast--ok svg  { color: var(--ok); }
.toast--warn     { border-color: var(--warn-line); }
.toast--warn svg { color: var(--warn); }
.toast--error     { border-color: var(--danger-line); }
.toast--error svg { color: var(--danger); }

.toast__text { flex: 1 1 auto; }

.toast__close {
  flex: 0 0 auto;
  color: var(--text3);
  line-height: 0;
}

.toast__close:hover { color: var(--text); }

@keyframes uora-toast-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

@keyframes uora-toast-out {
  from { opacity: 1; }
  to   { opacity: 0; transform: translateY(6px); }
}

/* ================================================================ tabs ====
   Markup: role="tablist" > button[role=tab][aria-selected] and
   div[role=tabpanel][hidden]. The arbitrator case room is built on these. */

.tabs {
  display: flex;
  gap: var(--s-1);
  border-block-end: var(--hairline) solid var(--border);
  overflow-x: auto;
  scrollbar-width: thin;
}

.tab {
  position: relative;
  padding: var(--s-3) var(--s-4);
  border: 0;
  background: none;
  color: var(--text2);
  font-size: var(--fs-small);
  font-weight: var(--fw-ui);
  letter-spacing: var(--tr-ui);
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--t-fast) var(--ease);
}

.tab:hover { color: var(--text); }

.tab[aria-selected="true"] {
  color: var(--accent);
}

.tab[aria-selected="true"]::after {
  content: '';
  position: absolute;
  inset-inline: var(--s-3);
  inset-block-end: -1px;
  height: 2px;
  background: var(--accent);
  border-radius: var(--r-pill);
}

.tab__count {
  margin-inline-start: var(--s-2);
  padding: 1px 6px;
  border-radius: var(--r-pill);
  background: var(--bg-3);
  color: var(--text2);
  font-size: var(--fs-micro);
  font-variant-numeric: tabular-nums;
}

.tabpanel {
  padding-block-start: var(--s-5);
}

.tabpanel[hidden] { display: none; }

/* ========================================================= empty state ==== */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-9) var(--s-5);
  text-align: center;
  border: 1px dashed var(--border2);
  border-radius: var(--r);
  color: var(--text2);
}

.empty__icon svg {
  width: 34px;
  height: 34px;
  color: var(--text3);
}

.empty__title {
  font-family: var(--font-display);
  font-size: var(--fs-h3);
  font-weight: var(--fw-strong);
  letter-spacing: var(--tr-card);
  color: var(--text);
}

.empty__body {
  max-width: 46ch;
  font-size: var(--fs-small);
}

/* ========================================================== skeleton ===== */

.skeleton {
  position: relative;
  overflow: hidden;
  background: var(--bg-3);
  border-radius: var(--r-sm);
  color: transparent;
  user-select: none;
}

.skeleton::after {
  content: '';
  position: absolute;
  inset: 0;
  transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .05), transparent);
  animation: uora-skeleton 1.4s infinite;
}

.skeleton--text {
  height: 0.85em;
  margin-block: 0.28em;
  border-radius: var(--r-pill);
}

.skeleton--title { height: 1.2em; width: 40%; }
.skeleton--line  { width: 100%; }
.skeleton--short { width: 60%; }
.skeleton--block { height: 120px; border-radius: var(--r); }
.skeleton--chip  { height: 20px; width: 92px; border-radius: var(--r-pill); }

@keyframes uora-skeleton {
  100% { transform: translateX(100%); }
}

/* ============================================================= notices ====
   A standing message about the case or the account. Distinct from a toast: this
   persists and may carry an action. */

.notice {
  display: flex;
  gap: var(--s-3);
  padding: var(--s-4);
  border: var(--hairline) solid var(--border2);
  border-radius: var(--r);
  background: var(--bg-2);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  color: var(--text2);
}

.notice svg {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  margin-block-start: 2px;
  color: var(--text3);
}

.notice__title {
  display: block;
  margin-block-end: var(--s-1);
  font-weight: var(--fw-strong);
  color: var(--text);
}

.notice--accent { border-color: var(--accent-line); background: var(--accent-soft); }
.notice--accent svg { color: var(--accent); }
.notice--ok     { border-color: var(--ok-line);     background: var(--ok-soft); }
.notice--ok svg { color: var(--ok); }
.notice--warn     { border-color: var(--warn-line);   background: var(--warn-soft); }
.notice--warn svg { color: var(--warn); }
.notice--danger     { border-color: var(--danger-line); background: var(--danger-soft); }
.notice--danger svg { color: var(--danger); }

/* ======================================================= document view ====
   A generated document previewed inside a dark app page. Setting
   data-surface="document" on the wrapper swaps the whole token set, so every
   component inside it renders in the light document palette without a second
   set of classes. */

.document-view {
  background: var(--bg);
  color: var(--text);
  border-radius: var(--r);
  border: var(--hairline) solid var(--border2);
  padding: clamp(24px, 5vw, 56px);
  font-size: 14px;
  line-height: var(--lh-body);
}

.document-view h1,
.document-view h2,
.document-view h3 {
  font-family: var(--font-display);
  color: var(--text);
}

.document-view a { color: var(--accent); }

.document-view [dir="rtl"] {
  text-align: right;
}

/* The bilingual documents put English first, then Arabic, separated by a rule. */
.document-view .lang-break {
  margin-block: var(--s-8);
  border-block-start: 2px solid var(--accent-line);
}

/* Icons follow the Lucide conventions everywhere: line, 24x24 grid, round caps,
   currentColor. */
.icon {
  display: inline-block;
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: middle;
  flex: 0 0 auto;
}

.icon--12 { width: 12px; height: 12px; stroke-width: 1.5; }
.icon--14 { width: 14px; height: 14px; stroke-width: 1.5; }
.icon--18 { width: 18px; height: 18px; }
.icon--24 { width: 24px; height: 24px; }
.icon--32 { width: 32px; height: 32px; }

/* ======================================================= misc utilities === */

.is-hidden,
[hidden] { display: none !important; }

.nowrap { white-space: nowrap; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.full { width: 100%; }
.center { text-align: center; }
.end { text-align: end; }
.grow { flex: 1 1 auto; min-width: 0; }

.mt-0 { margin-block-start: 0; }
.mt-2 { margin-block-start: var(--s-2); }
.mt-3 { margin-block-start: var(--s-3); }
.mt-4 { margin-block-start: var(--s-4); }
.mt-6 { margin-block-start: var(--s-6); }
.mb-2 { margin-block-end: var(--s-2); }
.mb-4 { margin-block-end: var(--s-4); }
.mb-6 { margin-block-end: var(--s-6); }

/* ====================================================== reduced motion ==== */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .skeleton::after { animation: none; }
}

/* ============================================== forced colours (Windows) ==
   In forced-colours mode the tinted chips lose their fill, so the border is what
   remains: make it explicit rather than transparent. */

@media (forced-colors: active) {
  .chip,
  .btn,
  .card,
  .table-wrap {
    border-color: currentColor;
  }

  .tab[aria-selected="true"]::after {
    background: currentColor;
  }
}

/* The wordmark is an image lockup, not type. Digital minimum from p9 is a
   160 px full lockup / 20 px symbol; the compact mark here sits comfortably
   above the symbol minimum. */
.wordmark__img {
  display: block;
  height: 32px;
  width: auto;
}
