/* Atlas components — every shared component of the design system.
 *
 * Spec: docs/design/Atlas_Experience_Redesign.md §6 (6.1–6.27; the Atlas AI
 * components of §6.28 live in atlas-ai.css). Canonical reference:
 * docs/design/Atlas_Design_System.md. Values come only from atlas-tokens.css.
 * Class names match docs/design/atlas-reference.html.
 *
 * Modules extend this file through its owner; they never ship their own
 * button, input, chip, pill, card, tab, dialog or colour, and they never
 * resize a shared control (touch sizes are set here under pointer: coarse).
 */
@layer atlas.components {
/* ==========================================================================
   Global feedback (spec §4.11): offline bar and app loading line
   ========================================================================== */
.atlas-offline-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 36px;
  padding: 0 var(--page-gutter);
  background: var(--warning-soft);
  color: var(--warning);
  font: var(--type-label);
  text-align: center;
}
.atlas-offline-bar > svg { width: var(--icon-sm); height: var(--icon-sm); color: var(--warning-icon); }
.atlas-loading-line {
  position: relative;
  height: 2px;
  overflow: hidden;
  background: transparent;
}
.atlas-loading-line::after {
  content: '';
  position: absolute;
  inset: 0 auto 0 0;
  width: 40%;
  background: var(--accent);
  animation: atlas-loading-line 1.2s var(--ease-in-out) infinite;
}
@keyframes atlas-loading-line { from { transform: translateX(-100%); } to { transform: translateX(250%); } }

/* ==========================================================================
   6.1 Page header — .page-head
   ========================================================================== */
/* The title column never shrinks below 280 px (or the full width when the
   page is narrower): when the actions don't fit beside it they wrap onto
   their own line under the title instead of squeezing the subtitle. */
.page-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-4) var(--s-6);
  min-width: 0;
}
.page-head__text { flex: 1 1 280px; min-width: min(100%, 280px); max-width: 100%; }
.page-head__title {
  margin: 0;
  font: var(--type-title);
  letter-spacing: var(--track-title);
  color: var(--text);
}
.page-head__sub {
  margin: var(--s-1) 0 0;
  font: var(--type-body);
  color: var(--text-2);
}
.page-head__actions { display: flex; flex-wrap: wrap; gap: var(--s-2); flex: 0 1 auto; min-width: 0; max-width: 100%; }
/* Page entry: the header and the summary/KPI row fade in with a tiny rise once,
   on load. The keyframe ENDS at opacity 1 and the elements' resting state is
   fully visible, so nothing waits on JS — if the animation never runs they are
   simply shown. Dense lists and table rows are deliberately excluded so live
   updates never flicker. Reduced motion collapses the rise (--move-sm → 0) and
   the global rule (atlas-base.css) cuts the duration, leaving an instant show. */
.page-head, .atlas-stats { animation: atlas-enter var(--motion-slow) var(--ease-out); }
@keyframes atlas-enter { from { opacity: 0; transform: translateY(var(--move-sm)); } to { opacity: 1; transform: none; } }
/* Text that carries user content wraps even a very long unbroken token inside
   its (min-width: 0) column instead of overflowing the page. Leaf text
   elements break anywhere; the containers (card, sheet and dialog bodies)
   only break a token that cannot fit on its own line (break-word), so the
   labels, steps and table headers inside them never split mid-word. */
:is(.page-head__title, .page-head__sub, .atlas-row__title, .atlas-row__meta, .atlas-card__title, .atlas-sheet__title, .atlas-sheet__desc, .atlas-dialog__title, .atlas-alert__title, .atlas-alert__body, .atlas-empty__title, .atlas-empty__text, .atlas-stat__detail) { overflow-wrap: anywhere; }
:is(.atlas-card__body, .atlas-sheet__body, .atlas-dialog__body) { overflow-wrap: break-word; }
/* Page rhythm (spec §5.4): header → tabs 16, tabs → toolbar 20, toolbar → content 12. */
.page-head + .atlas-tabs { margin-top: var(--s-4); }
.page-head + .atlas-toolbar { margin-top: var(--s-5); }
.atlas-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin: var(--s-5) 0 var(--s-3);
  min-width: 0;
}
.atlas-toolbar .atlas-search { width: 280px; max-width: 100%; }
.atlas-toolbar__end { display: flex; align-items: center; gap: var(--s-2); margin-left: auto; font: var(--type-meta); color: var(--text-2); }
@media (max-width: 767px) {
  .page-head { flex-direction: column; align-items: stretch; gap: var(--s-4); }
  /* In the column the 280 px basis would be a height: the text takes its content height. */
  .page-head__text { flex: none; }
  /* The phone top bar shows the page name; the H1 stays for assistive tech. */
  .page-head__title {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .page-head__sub { margin-top: 0; }
  .page-head__actions > .atlas-btn { flex: 1 1 0; }
  .atlas-toolbar {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    margin: var(--s-3) calc(-1 * var(--page-gutter));
    padding-inline: var(--page-gutter);
    /* The row scrolls sideways: controls past the edge fade out under the
       right gutter (as the tab strips do) instead of being cut mid-label. */
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - var(--page-gutter)), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - var(--page-gutter)), transparent);
  }
  /* A mask clips every descendant, fixed-position popovers included: while a
     menu opened from the toolbar is showing, drop the fade. */
  .atlas-toolbar:has([aria-expanded="true"]) { -webkit-mask-image: none; mask-image: none; }
  .atlas-toolbar__end { display: none; }
  /* The toolbar scrolls sideways on phones; the search keeps a usable width
     instead of shrinking to its icon. */
  .atlas-toolbar > .atlas-search { flex: 0 0 240px; min-width: 200px; }
}

/* Text link used as an action — a <button> or <a> that reads as a link
   ("Show all items", a post title that opens it). */
.atlas-link {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-text);
  font: inherit;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.atlas-link:hover { text-decoration: underline; text-underline-offset: 2px; }

/* ==========================================================================
   6.2 Section header — .atlas-section__head
   ========================================================================== */
.atlas-section { margin-top: var(--s-10); }
.atlas-section:first-child { margin-top: 0; }
.atlas-section__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-3);
}
.atlas-section__title {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin: 0;
  font: var(--type-section);
  letter-spacing: var(--track-section);
  color: var(--text);
}
.atlas-section__meta { font: var(--type-meta); color: var(--text-2); }
.atlas-section__link { font: var(--type-label); color: var(--accent-text); white-space: nowrap; }
@media (max-width: 767px) { .atlas-section { margin-top: 28px; } }

/* ==========================================================================
   6.3 Buttons — .atlas-btn
   ========================================================================== */
.atlas-btn {
  --spin-track: rgba(11, 15, 20, .16);
  --spin-head: var(--text-2);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  height: var(--control-md);
  min-width: 0;
  margin: 0;
  padding: 0 16px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);   /* ALCEDO: pill buttons, like the website */
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-1);
  font: 600 14px/20px var(--font-sans);
  letter-spacing: 0;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
  transition: background-color var(--motion-fast) var(--ease-out), border-color var(--motion-fast) var(--ease-out), color var(--motion-fast) var(--ease-out), box-shadow var(--motion-fast) var(--ease-out), transform var(--motion-fast) var(--ease-out);
}
.atlas-btn:hover { text-decoration: none; }
/* Tactile feedback: a gentle lift on hover, a small press on active. Both read
   the movement token, so prefers-reduced-motion collapses them to no movement
   while the colour states above stay visible. Disabled buttons never move. */
.atlas-btn:hover:not(:disabled, [aria-disabled="true"]) { transform: translateY(calc(var(--move-sm) * -0.25)); }
.atlas-btn:active:not(:disabled, [aria-disabled="true"]) { transform: translateY(calc(var(--move-sm) * 0.25)); }
.atlas-btn > svg, .atlas-btn > .icon { width: var(--icon-sm); height: var(--icon-sm); flex: none; margin-left: -2px; }
.atlas-btn > svg:last-child:not(:first-child), .atlas-btn > .icon:last-child:not(:first-child) { margin-left: 0; margin-right: -2px; }
.atlas-btn:focus-visible { outline: var(--focus-outline); outline-offset: var(--focus-offset); }

/* ALCEDO primary CTA: vivid orange fill with INK text and an orange glow,
   matching the website's .btn--orange. Orange + ink reads ~5.5:1 (AA). */
.atlas-btn--primary {
  --spin-track: rgba(16, 32, 31, .28);
  --spin-head: var(--text);
  border-color: transparent;
  background: var(--highlight);
  color: var(--text);
  box-shadow: 0 14px 28px -16px rgba(232, 115, 42, .9);
}
.atlas-btn--primary:hover:not(:disabled, [aria-disabled="true"]) { background: #EC8240; }
.atlas-btn--primary:active:not(:disabled, [aria-disabled="true"]) { background: #d9631f; }

/* Deep-teal emphasis button: brand dark fill with ivory text, the website's
   .btn--dark. For key secondary actions and dark panels. */
.atlas-btn--brand {
  --spin-track: rgba(248, 245, 237, .45);
  --spin-head: var(--atlas-snow);
  border-color: transparent;
  background: var(--accent);
  color: var(--text-on-accent);
  box-shadow: none;
}
.atlas-btn--brand:hover:not(:disabled, [aria-disabled="true"]) { background: #0A566C; }
.atlas-btn--brand:active:not(:disabled, [aria-disabled="true"]) { background: var(--accent-hover); }

.atlas-btn--secondary { border-color: var(--line-strong); background: var(--surface); color: var(--text); box-shadow: var(--shadow-1); }
.atlas-btn--secondary:hover:not(:disabled, [aria-disabled="true"]) { background: var(--bg-subtle); }
.atlas-btn--secondary:active:not(:disabled, [aria-disabled="true"]) { background: var(--bg-muted); }

.atlas-btn--ghost { border-color: transparent; background: transparent; color: var(--text); box-shadow: none; }
.atlas-btn--ghost:hover:not(:disabled, [aria-disabled="true"]),
.atlas-btn--ghost:active:not(:disabled, [aria-disabled="true"]) { background: var(--bg-muted); }

.atlas-btn--danger { border-color: var(--line-strong); background: var(--surface); color: var(--danger); box-shadow: var(--shadow-1); }
.atlas-btn--danger:hover:not(:disabled, [aria-disabled="true"]) { background: var(--danger-soft); }
.atlas-btn--danger:active:not(:disabled, [aria-disabled="true"]) { background: var(--danger-soft); border-color: var(--danger); }

.atlas-btn--danger-solid {
  --spin-track: rgba(255, 255, 255, .45);
  --spin-head: #ffffff;
  border-color: transparent;
  background: var(--danger);
  color: #ffffff;
  box-shadow: none;
}
.atlas-btn--danger-solid:hover:not(:disabled, [aria-disabled="true"]) { background: #a51b1b; }
.atlas-btn--danger-solid:active:not(:disabled, [aria-disabled="true"]) { background: #8a1616; }

.atlas-btn--sm { height: var(--control-sm); padding: 0 10px; font-size: 13px; line-height: 18px; }
.atlas-btn--lg { height: var(--control-lg); padding: 0 18px; font-size: 15px; line-height: 20px; }
.atlas-btn--block { display: flex; width: 100%; }

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

/* Loading: the label keeps the width, a spinner sits in the centre. */
.atlas-btn.is-loading { color: transparent; pointer-events: none; }
.atlas-btn.is-loading > * { visibility: hidden; }
.atlas-btn.is-loading::after {
  content: '';
  position: absolute;
  inset: 0;
  width: 16px;
  height: 16px;
  margin: auto;
  border: 2px solid var(--spin-track);
  border-top-color: var(--spin-head);
  border-radius: 50%;
  animation: atlas-spin 700ms linear infinite;
}
@keyframes atlas-spin { to { transform: rotate(360deg); } }

.atlas-btn-group { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }

/* ==========================================================================
   6.4 Icon button — .atlas-icon-btn
   ========================================================================== */
.atlas-icon-btn {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: var(--control-md);
  height: var(--control-md);
  flex: none;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease-out), color var(--dur-1) var(--ease-out);
}
.atlas-icon-btn > svg, .atlas-icon-btn > .icon { width: var(--icon-sm); height: var(--icon-sm); }
.atlas-icon-btn--md > svg, .atlas-icon-btn--md > .icon { width: var(--icon-md); height: var(--icon-md); }
.atlas-icon-btn--lg > svg, .atlas-icon-btn--lg > .icon { width: var(--icon-lg); height: var(--icon-lg); }
.atlas-icon-btn--sm { width: var(--control-sm); height: var(--control-sm); }
.atlas-icon-btn:hover:not(:disabled) { background: var(--bg-muted); color: var(--text); }
.atlas-icon-btn[aria-pressed="true"], .atlas-icon-btn[aria-expanded="true"] { background: var(--bg-muted); color: var(--text); }
.atlas-icon-btn:focus-visible { outline: var(--focus-outline); outline-offset: var(--focus-offset); }
.atlas-icon-btn:disabled { opacity: .45; cursor: not-allowed; }
.atlas-icon-btn .dot {
  position: absolute;
  top: 7px;
  right: 8px;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--danger);
  box-shadow: 0 0 0 2px var(--bg);
}

/* Keyboard hint */
.kbd, .atlas-kbd {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  height: 20px;
  padding: 0 6px;
  border: 1px solid var(--line);
  border-radius: var(--r-xs);
  background: var(--surface);
  color: var(--text-2);
  font: 500 12px/1 var(--font-sans);
}

/* Touch: every control is at least 44 px tall (spec §6). */
/* Touch: every shared control is at least 44 px (spec §5.4, G17). */
@media (pointer: coarse) {
  .atlas-btn { height: var(--control-lg); }
  .atlas-btn--sm { height: var(--touch); }
  .atlas-icon-btn, .atlas-icon-btn--sm { width: var(--touch); height: var(--touch); }
}

/* ==========================================================================
   6.5 Inputs — .atlas-input, .atlas-select, textarea, date/time, search
   ========================================================================== */
.atlas-input,
.atlas-select,
.atlas-textarea {
  display: block;
  width: 100%;
  min-width: 0;
  height: var(--control-md);
  margin: 0;
  padding: 0 12px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--text);
  box-shadow: none;
  font: 400 14px/20px var(--font-sans);
  outline: none;
  transition: border-color var(--dur-1) var(--ease-out), box-shadow var(--dur-1) var(--ease-out);
}
.atlas-input::placeholder, .atlas-textarea::placeholder { color: var(--text-3); opacity: 1; }
.atlas-input:hover:not(:disabled, :focus),
.atlas-select:hover:not(:disabled, :focus),
.atlas-textarea:hover:not(:disabled, :focus) { border-color: var(--line-hover); }
.atlas-input:focus,
.atlas-select:focus,
.atlas-textarea:focus { border-color: var(--accent-brand); box-shadow: var(--focus-ring); outline: none; }
.atlas-input[aria-invalid="true"],
.atlas-select[aria-invalid="true"],
.atlas-textarea[aria-invalid="true"] { border-color: var(--danger); box-shadow: 0 0 0 3px var(--danger-ring); }
.atlas-input:disabled,
.atlas-select:disabled,
.atlas-textarea:disabled { background: var(--bg-subtle); color: var(--text-3); border-color: var(--line); cursor: not-allowed; opacity: 1; }
.atlas-select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 34px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235b616b' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  background-size: 16px 16px;
  text-overflow: ellipsis;
}
textarea.atlas-input,
.atlas-textarea {
  height: auto;
  min-height: 80px;          /* 3 rows */
  max-height: 220px;         /* 10 rows, then it scrolls */
  padding: 10px 12px;
  resize: vertical;
  field-sizing: content;
}
/* Native date and time pickers (the platform control; the value stays ISO). */
.atlas-input[type="date"],
.atlas-input[type="time"],
.atlas-input[type="datetime-local"] { padding-right: 8px; font-variant-numeric: tabular-nums; }
.atlas-input[type="number"] { font-variant-numeric: tabular-nums; }
.atlas-range { display: flex; align-items: center; gap: var(--s-2); }
.atlas-range > span { color: var(--text-2); font: var(--type-meta); }

/* Affix: units after the value ("ml", "kr", "°C"). */
.atlas-affix { position: relative; display: block; }
.atlas-affix > .atlas-input { padding-right: 44px; }
.atlas-affix > .suffix,
.atlas-affix > .atlas-affix__suffix {
  position: absolute;
  top: 50%;
  right: 12px;
  transform: translateY(-50%);
  color: var(--text-2);
  font: var(--type-meta);
  pointer-events: none;
}

/* Search: 16 px icon at 11 px, 34 px text inset, clear button when filled. */
.atlas-search:has(> .atlas-input) { position: relative; display: block; min-width: 0; }
.atlas-search:has(> .atlas-input) > :is(svg, .icon):first-child {
  position: absolute;
  top: 50%;
  left: 11px;
  width: var(--icon-sm);
  height: var(--icon-sm);
  transform: translateY(-50%);
  color: var(--text-3);
  pointer-events: none;
}
.atlas-search > .atlas-input { padding-left: 34px; padding-right: 34px; }
.atlas-search > .atlas-input::-webkit-search-cancel-button { display: none; }
.atlas-search__clear {
  position: absolute;
  top: 50%;
  right: 4px;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-2);
  transform: translateY(-50%);
  cursor: pointer;
}
.atlas-search__clear:hover { background: var(--bg-muted); color: var(--text); }
.atlas-search__clear > svg { width: 14px; height: 14px; }
.atlas-search > .atlas-input:placeholder-shown ~ .atlas-search__clear { display: none; }

@media (pointer: coarse) {
  .atlas-input, .atlas-select { height: var(--control-lg); font-size: 16px; }
  .atlas-textarea, textarea.atlas-input { font-size: 16px; }
}

/* ==========================================================================
   6.6 Field and 6.7 Forms
   ========================================================================== */
.atlas-field { display: grid; gap: 6px; min-width: 0; }
.atlas-field > label,
.atlas-label {
  display: block;
  margin: 0;
  font: var(--type-label);
  letter-spacing: 0;
  text-transform: none;
  color: var(--text);
}
/* The "(optional)" suffix in a form label: a muted, lighter, slightly spaced
   secondary note. One consistent rule wherever it is used. */
.optional {
  margin-left: var(--s-1);
  color: var(--text-3);
  font-weight: 400;
  font-size: var(--fs-caption);
  letter-spacing: .01em;
}
.atlas-field .help,
.atlas-field__help { margin: 0; font: var(--type-caption); color: var(--text-2); }
.atlas-field .error,
.atlas-field__error {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font: var(--type-caption);
  color: var(--danger);
}
.atlas-field .error > svg,
.atlas-field__error > svg { width: 14px; height: 14px; flex: none; }

.atlas-form { display: grid; gap: var(--s-6); min-width: 0; }
.atlas-form-group { display: grid; gap: var(--s-4); min-width: 0; }
/* fieldset.atlas-form-group: the base fieldset reset applies; the legend is the
   group title and sits above the grid. */
.atlas-form-group > legend { margin-bottom: var(--s-2); }
.atlas-form-group__title { margin: 0; padding-top: var(--s-1); font: var(--type-heading); color: var(--text); }
.atlas-grid-2 { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--s-3) var(--s-4); }
.atlas-form-foot { display: flex; align-items: center; justify-content: flex-end; gap: var(--s-2); }
.atlas-form-foot__start { margin-right: auto; }
@media (max-width: 767px) {
  .atlas-grid-2 { grid-template-columns: minmax(0, 1fr); }
  .atlas-form-foot > .atlas-btn { flex: 1 1 0; }
}

/* ==========================================================================
   6.8 Toggle — button.atlas-toggle[role="switch"][aria-checked]
   ========================================================================== */
.atlas-toggle {
  position: relative;
  display: inline-block;
  width: 36px;
  height: 20px;
  flex: none;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--toggle-off);
  cursor: pointer;
  transition: background-color var(--dur-2) var(--ease-out);
}
.atlas-toggle::before { content: ''; position: absolute; inset: -12px -4px; }   /* 44 px hit area */
.atlas-toggle::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: #ffffff;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .2);
  transition: transform var(--dur-2) var(--ease-out);
}
.atlas-toggle[aria-checked="true"] { background: var(--accent); }
.atlas-toggle[aria-checked="true"]::after { transform: translateX(16px); }
.atlas-toggle:focus-visible { outline: var(--focus-outline); outline-offset: var(--focus-offset); }
.atlas-toggle:disabled, .atlas-toggle[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
/* Waiting for the server: a spinner replaces the thumb. */
.atlas-toggle.is-pending::after {
  background: transparent;
  box-shadow: none;
  border: 2px solid rgba(255, 255, 255, .5);
  border-top-color: #ffffff;
  animation: atlas-spin 700ms linear infinite;
}
.atlas-toggle.is-pending:not([aria-checked="true"])::after { border-color: rgba(11, 15, 20, .12); border-top-color: var(--text-2); }
.atlas-toggle-row { display: flex; align-items: flex-start; justify-content: space-between; gap: var(--s-4); min-width: 0; }
.atlas-toggle-row__label, .atlas-toggle-row .t { margin: 0; font: 500 14px/20px var(--font-sans); color: var(--text); }
.atlas-toggle-row__help, .atlas-toggle-row .h { margin: 2px 0 0; font: var(--type-caption); color: var(--text-2); }
.atlas-toggle-row__error { margin: 2px 0 0; font: var(--type-caption); color: var(--danger); }
.atlas-toggle-row > .atlas-toggle { margin-top: 2px; }

/* ==========================================================================
   6.9 Checkbox and radio — native inputs, visually replaced
   ========================================================================== */
.atlas-check,
.atlas-radio {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 16px;
  height: 16px;
  flex: none;
  margin: 0;
  border: 1.5px solid var(--control-border);
  background: var(--surface);
  appearance: none;
  -webkit-appearance: none;
  cursor: pointer;
  vertical-align: middle;
  transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}
.atlas-check { border-radius: var(--r-xs); }
.atlas-radio { border-radius: 50%; }
.atlas-check:checked,
.atlas-check:indeterminate,
.atlas-check.is-on,
.atlas-check[aria-checked="true"],
.atlas-check[aria-checked="mixed"] { border-color: var(--accent); background: var(--accent); }
.atlas-check:checked::after,
.atlas-check.is-on::after,
.atlas-check[aria-checked="true"]::after {
  content: '';
  width: 8px;
  height: 4px;
  border-left: 2px solid #ffffff;
  border-bottom: 2px solid #ffffff;
  transform: translate(0, -1px) rotate(-45deg);
}
.atlas-check:indeterminate::after,
.atlas-check[aria-checked="mixed"]::after { content: ''; width: 8px; height: 2px; border-radius: 1px; background: #ffffff; }
.atlas-radio:checked { border-color: var(--accent); background: var(--accent); box-shadow: inset 0 0 0 3px var(--surface); }
.atlas-check:focus-visible, .atlas-radio:focus-visible { outline: var(--focus-outline); outline-offset: var(--focus-offset); }
.atlas-check:disabled, .atlas-radio:disabled { opacity: .45; cursor: not-allowed; }
/* The whole label row is the hit area. */
.atlas-check-row {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-height: var(--control-sm);
  font: var(--type-body);
  color: var(--text);
  cursor: pointer;
}
@media (pointer: coarse) { .atlas-check-row { min-height: var(--touch); } }

/* ==========================================================================
   6.10 Segmented control — .atlas-segmented
   ========================================================================== */
.atlas-segmented {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border-radius: var(--r-md);
  background: var(--bg-muted);
  max-width: 100%;
}
.atlas-segmented > button,
.atlas-segmented > a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: 28px;
  margin: 0;
  padding: 0 12px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--text-2);
  font: var(--type-label);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-2) var(--ease-out), color var(--dur-2) var(--ease-out);
}
.atlas-segmented > :is(button, a):hover { color: var(--text); text-decoration: none; }
.atlas-segmented > :is(button, a):is([aria-pressed="true"], [aria-checked="true"], [aria-current="page"], .is-active) {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 1px 2px rgba(11, 15, 20, .08), 0 0 0 1px rgba(11, 15, 20, .04);
}
.atlas-segmented > :is(button, a):focus-visible { outline: var(--focus-outline); outline-offset: 0; }
.atlas-segmented > :is(button, a) > svg { width: var(--icon-sm); height: var(--icon-sm); }
@media (pointer: coarse) { .atlas-segmented > :is(button, a) { height: var(--touch); } }

/* ==========================================================================
   6.11 Tabs — .atlas-tabs (page-level peers; links with routes)
   ========================================================================== */
.atlas-tabs {
  display: flex;
  gap: var(--s-6);
  min-width: 0;
  border-bottom: 1px solid var(--line);
  overflow-x: auto;
  scrollbar-width: none;
}
.atlas-tabs::-webkit-scrollbar { display: none; }
.atlas-tabs > a,
.atlas-tabs > button,
.atlas-tabs > [role="tab"] {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 40px;
  flex: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text-2);
  font: 500 14px/20px var(--font-sans);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: color var(--motion-mid) var(--ease-out);
}
.atlas-tabs > :is(a, button, [role="tab"]):hover { color: var(--text); text-decoration: none; }
.atlas-tabs > :is(a, button, [role="tab"]):is([aria-current="page"], [aria-selected="true"], .is-active) { color: var(--text); }
.atlas-tabs > :is(a, button, [role="tab"]):is([aria-current="page"], [aria-selected="true"], .is-active)::after {
  content: '';
  position: absolute;
  top: auto;
  left: 0;
  right: 0;
  bottom: -1px;
  width: auto;
  height: 2px;
  border-radius: 2px;
  background: var(--highlight);   /* ALCEDO: selected-tab indicator is orange (active label stays ink) */
  transform: none;
  /* The orange underline grows in from its centre when a tab becomes active. */
  transform-origin: center;
  animation: atlas-tab-underline var(--motion-mid) var(--ease-out);
}
@keyframes atlas-tab-underline { from { opacity: 0; transform: scaleX(.4); } to { opacity: 1; transform: scaleX(1); } }
.atlas-tabs > :is(a, button, [role="tab"]):focus-visible { outline: var(--focus-outline); outline-offset: -2px; border-radius: var(--r-sm); }
.atlas-tabs .count {
  padding: 1px 6px;
  border-radius: var(--r-pill);
  background: var(--neutral-soft);
  color: var(--text-2);
  font: var(--type-caption);
}
@media (max-width: 767px) {
  .atlas-tabs {
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
    mask-image: linear-gradient(to right, #000 calc(100% - 24px), transparent);
    padding-right: var(--s-6);
  }
}
@media (pointer: coarse) { .atlas-tabs > :is(a, button, [role="tab"]) { height: var(--touch); } }

/* ==========================================================================
   6.12 Chips — .atlas-chip
   ========================================================================== */
.atlas-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  flex: none;
  margin: 0;
  padding: 0 10px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  background: var(--surface);
  color: var(--text);
  font: var(--type-label);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}
.atlas-chip:hover { background: var(--bg-subtle); text-decoration: none; }
.atlas-chip > svg, .atlas-chip > .icon { width: var(--icon-sm); height: var(--icon-sm); color: var(--text-2); }
.atlas-chip.is-active,
.atlas-chip[aria-pressed="true"] { border-color: transparent; background: var(--accent-soft); color: var(--accent-text); }
.atlas-chip.is-active:hover,
.atlas-chip[aria-pressed="true"]:hover { background: var(--accent-soft-hover); }
.atlas-chip.is-active > :is(svg, .icon),
.atlas-chip[aria-pressed="true"] > :is(svg, .icon) { color: var(--accent-text); }
.atlas-chip--dashed { border-style: dashed; color: var(--text-2); }
.atlas-chip__clear {
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  margin-right: -4px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.atlas-chip__clear:hover { background: rgba(37, 99, 235, .12); }
.atlas-chip__clear > svg { width: 12px; height: 12px; }
.atlas-chip:focus-visible { outline: var(--focus-outline); outline-offset: var(--focus-offset); }
.atlas-chips { display: flex; flex-wrap: wrap; gap: var(--s-2); }
@media (pointer: coarse) { .atlas-chip { height: var(--touch); padding: 0 14px; } }

/* Record chip — a link to a record (a recipe an item is used in, a record
   attached to a message). 32 px; its touch hit area is 44 px (below). */
.atlas-record-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 100%;
  min-height: var(--control-sm);
  padding: 0 10px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  background: var(--surface);
  color: var(--text);
  font: var(--type-label);
  text-decoration: none;
}
a.atlas-record-chip:hover { border-color: var(--line-strong); background: var(--bg-subtle); text-decoration: none; }
.atlas-record-chip > span { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.atlas-record-chip > svg { width: var(--icon-sm); height: var(--icon-sm); flex: none; color: var(--text-2); }

/* ==========================================================================
   Touch hit areas (G20, spec §5.10): on coarse pointers every interactive
   element is at least 44 px. Controls with a box (buttons, inputs, chips,
   tabs, check rows) grow to 44 px above. Small inline controls — text
   links, section links, record chips, disclosure summaries, a chip's clear
   button, a linked cell — keep their visual size and get an invisible
   44 px hit area (::after) centred on them.
   The hit area never applies to the items of a tab set or segmented
   control: they already have a 44 px box, and a tab draws its indicator
   with ::after (a merged ::after moved the indicator through the label).
   ========================================================================== */
@media (pointer: coarse) {
  :is(.atlas-link, .atlas-section__link, .atlas-record-chip, .atlas-chip__clear, .atlas-hit, details > summary, a.cell-primary, a[href]:not([class])):not(:is(.atlas-tabs, .atlas-segmented) > *) { position: relative; }
  :is(.atlas-link, .atlas-section__link, .atlas-record-chip, .atlas-chip__clear, .atlas-hit, details > summary, a.cell-primary, a[href]:not([class])):not(:is(.atlas-tabs, .atlas-segmented) > *)::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: max(100%, var(--touch));
    height: max(100%, var(--touch));
    transform: translate(-50%, -50%);
  }
}

/* ==========================================================================
   6.13 Status pill and badge — .atlas-pill, .atlas-badge
   ========================================================================== */
.atlas-pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 22px;
  flex: none;
  padding: 0 8px;
  border-radius: var(--r-pill);
  background: var(--neutral-soft);
  color: var(--text-2);
  font: 500 12px/16px var(--font-sans);
  white-space: nowrap;
}
.atlas-pill::before { content: ''; width: 6px; height: 6px; flex: none; border-radius: 50%; background: currentColor; }
.atlas-pill--positive { background: var(--positive-soft); color: var(--positive); }
.atlas-pill--warning { background: var(--warning-soft); color: var(--warning); }
.atlas-pill--danger { background: var(--danger-soft); color: var(--danger); }
.atlas-pill--info { background: var(--accent-soft); color: var(--accent-text); }
.atlas-pill--neutral { background: var(--neutral-soft); color: var(--text-2); }
.atlas-pill--plain::before { display: none; }
.atlas-badge {
  display: inline-grid;
  place-items: center;
  min-width: 18px;
  height: 18px;
  flex: none;
  padding: 0 5px;
  border-radius: var(--r-pill);
  background: var(--highlight);   /* ALCEDO: primary badge/count is orange with ink text (~5.5:1 AA) */
  color: var(--text);
  font: 600 12px/1 var(--font-sans);
  font-variant-numeric: tabular-nums;
}
.atlas-badge--muted { background: var(--bg-muted); color: var(--text-2); }
.atlas-badge--brand { background: var(--accent); color: var(--text-on-accent); }   /* teal count, where orange would clash */

/* ==========================================================================
   6.14 Card — .atlas-card (white, hairline, 12 px radius, no shadow)
   ========================================================================== */
.atlas-card {
  min-width: 0;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-soft);   /* warm cream card lifts off the ivory canvas — set apart by hairline + soft teal shadow, not by whiteness */
  color: var(--text);
}
.atlas-card--pad { padding: var(--s-5); }
.atlas-card--pad-sm { padding: var(--s-4); }
.atlas-card--pad-lg { padding: var(--s-6); }
a.atlas-card, button.atlas-card, .atlas-card--link {
  display: block;
  width: 100%;
  font: inherit;
  text-align: left;
  text-decoration: none;
  color: inherit;
  cursor: pointer;
  transition: border-color var(--dur-1) var(--ease-out);
}
a.atlas-card:hover, button.atlas-card:hover, .atlas-card--link:hover { border-color: var(--line-strong); text-decoration: none; }
a.atlas-card:focus-visible, button.atlas-card:focus-visible, .atlas-card--link:focus-visible { outline: var(--focus-outline); outline-offset: var(--focus-offset); }
.atlas-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--line-subtle);
}
.atlas-card__title { margin: 0; font: var(--type-heading); color: var(--text); }
.atlas-card__body { padding: var(--s-5); }
.atlas-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-5);
  border-top: 1px solid var(--line-subtle);
}

/* ==========================================================================
   6.15 List row — .atlas-row inside .atlas-list
   ========================================================================== */
.atlas-list { margin: 0; padding: 0; list-style: none; }
.atlas-row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 60px;
  padding: 10px var(--s-4);
  border-top: 1px solid var(--line-subtle);
  color: var(--text);
  text-decoration: none;
}
.atlas-row:first-child { border-top: 0; }
.atlas-row--compact { min-height: 56px; }
a.atlas-row, button.atlas-row, .atlas-row--link {
  width: 100%;
  margin: 0;
  border-right: 0;
  border-bottom: 0;
  border-left: 0;
  background: transparent;
  font: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color var(--dur-1) var(--ease-out);
}
a.atlas-row:hover, button.atlas-row:hover, .atlas-row--link:hover { background: var(--bg-hover); text-decoration: none; }
a.atlas-row:focus-visible, button.atlas-row:focus-visible { outline: var(--focus-outline); outline-offset: -2px; }
/* Row link: the row's title is the link (.atlas-row__link, an <a> or a
   <button>) and the whole row is its hit area; controls in __end stay
   separately clickable above it. */
.atlas-row:has(.atlas-row__link) { position: relative; }
.atlas-row:has(.atlas-row__link):hover { background: var(--bg-hover); }
.atlas-row:has(.atlas-row__link:focus-visible) { outline: var(--focus-outline); outline-offset: -2px; }
.atlas-row__link {
  display: block;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text);
  font: 500 14px/20px var(--font-sans);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.atlas-row__link::after { content: ''; position: absolute; inset: 0; }
.atlas-row__link:hover { text-decoration: none; }
.atlas-row__link:focus-visible { outline: none; }
.atlas-row:has(.atlas-row__link) .atlas-row__end { position: relative; z-index: 1; }

/* Linked target: the record a deep link opened (#inventory/movements?movement=,
   #marketing?recommendation=, #settings/integrations?provider=). The module
   marks it .is-linked-target with aria-current="true": a brief accent wash
   that settles on a quiet accent edge. Static (no wash animation) with reduced
   motion. Table rows wash their cells. */
.is-linked-target, .atlas-table tr.is-linked-target > td {
  animation: atlas-linked-target 2400ms var(--ease-out) backwards;
}
.is-linked-target { box-shadow: inset 3px 0 0 var(--accent-brand); }
.atlas-table tr.is-linked-target { box-shadow: none; }
.atlas-table tr.is-linked-target > td:first-child { box-shadow: inset 3px 0 0 var(--accent-brand); }
@keyframes atlas-linked-target { 0%, 45% { background-color: var(--accent-soft); } 100% { background-color: transparent; } }
@media (prefers-reduced-motion: reduce) {
  .is-linked-target, .atlas-table tr.is-linked-target > td { animation: none; background-color: var(--accent-soft); }
}
html.atlas-reduce-motion :is(.is-linked-target, .atlas-table tr.is-linked-target > td) { animation: none; background-color: var(--accent-soft); }
.atlas-row__icon {
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: var(--r-md);
  background: var(--neutral-soft);
  color: var(--text-2);
}
.atlas-row__icon > svg { width: var(--icon-sm); height: var(--icon-sm); }
.atlas-row__icon--positive { background: var(--positive-soft); color: var(--positive); }
.atlas-row__icon--warning { background: var(--warning-soft); color: var(--warning-icon); }
.atlas-row__icon--danger { background: var(--danger-soft); color: var(--danger); }
.atlas-row__icon--info { background: var(--accent-soft); color: var(--accent); }
.atlas-row__body { flex: 1 1 auto; min-width: 0; }
.atlas-row__title { margin: 0; font: 500 14px/20px var(--font-sans); color: var(--text); overflow-wrap: anywhere; }
.atlas-row__meta { margin: 2px 0 0; font: var(--type-meta); color: var(--text-2); }
.atlas-row__end { display: flex; align-items: center; gap: var(--s-2); flex: none; }
.atlas-row__value { font: var(--type-num); font-variant-numeric: tabular-nums; text-align: right; }
.atlas-row__chevron { display: none; color: var(--text-3); }
@media (max-width: 767px) {
  .atlas-row { align-items: flex-start; padding: 12px 14px; }
  .atlas-row__end > .atlas-btn, .atlas-row__action { display: none; }
  .atlas-row__chevron { display: inline-grid; align-self: center; }
}

/* ==========================================================================
   6.16 Data table — .atlas-table in .atlas-table-wrap
   ========================================================================== */
.atlas-table-wrap {
  min-width: 0;
  max-width: 100%;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  overflow: auto;
  overscroll-behavior-inline: contain;
}
.atlas-table { width: 100%; border-collapse: separate; border-spacing: 0; font: var(--type-body); color: var(--text); }
.atlas-table th {
  overflow-wrap: break-word;   /* a long token wraps; never mid-word in a narrow column */
  position: sticky;
  top: var(--table-sticky-top, 0);
  z-index: 1;
  height: 36px;
  padding: 0 12px;
  border-bottom: 1px solid var(--line);
  background: var(--bg-subtle);
  color: var(--text-2);
  font: 500 12px/16px var(--font-sans);
  letter-spacing: 0;
  text-transform: none;
  text-align: left;
  white-space: nowrap;
}
.atlas-table th[aria-sort] { cursor: pointer; }
.atlas-th-sort, .th-sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.atlas-th-sort > svg, .th-sort > svg { width: 14px; height: 14px; visibility: hidden; }
th[aria-sort="ascending"] :is(.atlas-th-sort, .th-sort) > svg,
th[aria-sort="descending"] :is(.atlas-th-sort, .th-sort) > svg { visibility: visible; }
th[aria-sort="ascending"] :is(.atlas-th-sort, .th-sort) > svg { transform: rotate(180deg); }
.atlas-table td {
  height: 48px;
  padding: 0 12px;
  border-bottom: 1px solid var(--line-subtle);
  vertical-align: middle;
  white-space: nowrap;
}
.atlas-table tbody tr:last-child td { border-bottom: 0; }
.atlas-table tbody tr:hover td { background: var(--bg-hover); }
.atlas-table tbody tr:is(.is-selected, [aria-selected="true"]) td { background: var(--accent-soft); }
.atlas-table .is-num, .atlas-table [data-num] { text-align: right; font-variant-numeric: tabular-nums; }
.atlas-table .col-check { width: 40px; padding-right: 0; }
.atlas-table .col-actions { width: 48px; padding-right: 8px; text-align: right; }
.atlas-table .cell-primary { font-weight: 500; }
/* Truncated cell text: one line with an ellipsis inside a fixed-layout (or
   width-limited) column; put the full text in the cell's title. Use it on the
   td or on a span inside it. */
.atlas-table .cell-clip { display: block; min-width: 0; max-width: 100%; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.atlas-table td.cell-clip { display: table-cell; }
.atlas-table .cell-sub { display: block; margin-top: 1px; font: var(--type-caption); color: var(--text-2); }
.atlas-table .unit { margin-left: 2px; color: var(--text-2); font: var(--type-caption); }
.atlas-table .row-action { opacity: 0; transition: opacity var(--dur-1) var(--ease-out); }
.atlas-table tr:is(:hover, :focus-within, .is-selected) .row-action { opacity: 1; }
.atlas-table--compact td { height: 40px; }
.atlas-table-wrap--scroll { max-height: var(--table-max-height, 70vh); }
@media (pointer: coarse) { .atlas-table .row-action { opacity: 1; } }
/* Column priority: 3 hides at ≤1279, 2 and 3 at ≤1023. */
@media (max-width: 1279px) { .atlas-table [data-priority="3"] { display: none; } }
@media (max-width: 1023px) { .atlas-table [data-priority="2"] { display: none; } }
/* Par bar in a quantity cell: 44 × 4. */
.atlas-par { display: inline-block; width: 44px; height: 4px; margin-left: 8px; overflow: hidden; border-radius: 2px; background: var(--bg-muted); vertical-align: middle; }
.atlas-par > i { display: block; height: 100%; border-radius: 2px; background: var(--text-3); }
.atlas-par--warning > i { background: var(--warning-icon); }
.atlas-par--danger > i { background: var(--danger); }
/* Bulk bar: replaces the toolbar actions while rows are selected. */
.atlas-bulkbar {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 44px;
  margin-bottom: var(--s-3);
  padding: 0 var(--s-2) 0 14px;
  border-radius: var(--r-lg);
  background: var(--ink);
  color: #ffffff;
  font: 500 14px/20px var(--font-sans);
}
.atlas-bulkbar .atlas-btn--ghost { color: #ffffff; }
.atlas-bulkbar .atlas-btn--ghost:hover:not(:disabled) { background: rgba(255, 255, 255, .1); }
.atlas-bulkbar__sep { width: 1px; height: 20px; margin: 0 4px; background: rgba(255, 255, 255, .2); }
/* Sticky save bar (bulk edits such as par levels): pinned to the bottom of the
   viewport while its table scrolls, and visible on phones above the tab bar. */
.atlas-bulkbar--sticky {
  position: sticky;
  bottom: var(--s-4);
  z-index: 2;
  width: fit-content;
  margin: var(--s-4) 0 0 auto;
}
.atlas-table-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-3) var(--s-1);
  font: var(--type-meta);
  color: var(--text-2);
}
.atlas-table-foot > :first-child { flex: none; white-space: nowrap; }   /* the count ("3 files") never wraps */
/* Phone (<768): the table is replaced by a row list with the same state. */
.atlas-table-list { display: none; margin: 0; padding: 0; list-style: none; }
@media (max-width: 767px) {
  .atlas-table-wrap--responsive, .atlas-bulkbar { display: none; }
  .atlas-bulkbar--sticky { display: flex; bottom: calc(var(--tabbar-h) + var(--s-3) + env(safe-area-inset-bottom)); width: auto; margin-left: 0; }
  .atlas-table-list { display: block; margin-inline: calc(-1 * var(--page-gutter)); border-top: 1px solid var(--line); }
  .atlas-table-list__row {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    min-height: 64px;
    padding: 10px var(--page-gutter);
    border-bottom: 1px solid var(--line-subtle);
    color: var(--text);
    text-decoration: none;
  }
  /* A row that opens a sheet in place is a button: same row, no button chrome. */
  button.atlas-table-list__row { width: 100%; margin: 0; border-width: 0 0 1px; background: none; font: inherit; text-align: left; cursor: pointer; }
  .atlas-table-list__body { flex: 1 1 auto; min-width: 0; }
  .atlas-table-list__title { font: 500 15px/20px var(--font-sans); }
  .atlas-table-list__meta { margin-top: 2px; font: var(--type-meta); color: var(--text-2); }
  .atlas-table-list__value { font: 500 15px/20px var(--font-sans); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
}

/* ==========================================================================
   6.17 KPI / stat — .atlas-stat in an .atlas-stats row (hairlines, not cards)
   ========================================================================== */
.atlas-stats {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.atlas-stat { display: block; min-width: 0; padding: var(--s-5) var(--s-6) var(--s-5) 0; color: inherit; text-decoration: none; }
.atlas-stat + .atlas-stat { padding-left: var(--s-6); border-left: 1px solid var(--line); }
a.atlas-stat:hover { text-decoration: none; }
a.atlas-stat:hover .atlas-stat__link { color: var(--accent-text); }
.atlas-stat__label { display: flex; align-items: center; gap: var(--s-2); margin: 0; font: var(--type-label); color: var(--text-2); }
.atlas-stat__label > svg { width: var(--icon-sm); height: var(--icon-sm); }
.atlas-stat__value { margin: var(--s-2) 0 0; font: var(--type-kpi); letter-spacing: var(--track-kpi); font-variant-numeric: tabular-nums; color: var(--text); }
.atlas-stat__unit { margin-left: 6px; font: var(--type-body); letter-spacing: 0; color: var(--text-2); }
.atlas-stat__detail { margin: var(--s-1) 0 0; font: var(--type-meta); color: var(--text-2); }
.atlas-stat__link { display: inline-flex; align-items: center; gap: 4px; margin-top: var(--s-3); font: var(--type-label); color: var(--text-2); }
@media (max-width: 1023px) {
  .atlas-stat { padding-right: var(--s-4); }
  .atlas-stat + .atlas-stat { padding-left: var(--s-4); }
}
@media (max-width: 767px) {
  .atlas-stats { grid-auto-flow: row; grid-auto-columns: auto; border-bottom: 0; }
  .atlas-stat, .atlas-stat + .atlas-stat {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    column-gap: var(--s-4);
    padding: var(--s-4) 0;
    border-left: 0;
    border-bottom: 1px solid var(--line);
  }
  .atlas-stat__value { grid-column: 2; grid-row: 1 / span 2; margin: 0; }
  .atlas-stat__detail { grid-column: 1; }
  .atlas-stat__link { display: none; }
}

/* ==========================================================================
   6.18 Dialog and sheet (modal.js) — .atlas-scrim, .atlas-dialog, .atlas-sheet
   A modal.js root ([data-atlas-modal]) with class .atlas-modal is the scrim;
   its [data-modal-panel] is an .atlas-dialog or an .atlas-sheet.
   ========================================================================== */
body.atlas-modal-open { overflow: hidden; }
.atlas-scrim,
.atlas-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  background: var(--overlay);
  animation: atlas-fade-in var(--dur-3) var(--ease-out);
}
.atlas-modal { display: none; }
.atlas-modal.is-open { display: block; }
.atlas-dialog {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-overlay) + 1);
  display: flex;
  flex-direction: column;
  width: min(440px, calc(100% - 32px));
  height: fit-content;
  max-height: calc(100% - 32px);
  margin: auto;
  padding: var(--s-6);
  overflow: auto;
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--shadow-modal);
  color: var(--text);
  outline: none;
  animation: atlas-dialog-in var(--dur-3) var(--ease-out);
}
.atlas-dialog--form { width: min(560px, calc(100% - 32px)); }
.atlas-dialog__title { margin: 0; font: var(--type-section); letter-spacing: var(--track-section); color: var(--text); }
.atlas-dialog__body { margin-top: var(--s-2); font: var(--type-body); color: var(--text-2); }
.atlas-dialog__body > * + * { margin-top: var(--s-3); }
.atlas-dialog__foot { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: var(--s-2); margin-top: var(--s-6); }
.atlas-sheet {
  position: fixed;
  top: 8px;
  right: 8px;
  bottom: 8px;
  z-index: calc(var(--z-overlay) + 1);
  display: flex;
  flex-direction: column;
  width: min(480px, calc(100% - 16px));
  overflow: hidden;
  border-radius: var(--r-xl);
  background: var(--surface);
  box-shadow: var(--shadow-modal);
  color: var(--text);
  outline: none;
  animation: atlas-sheet-in var(--dur-3) var(--ease-out);
}
.atlas-sheet--wide { width: min(640px, calc(100% - 16px)); }
.atlas-sheet__grabber { display: none; }
.atlas-sheet__head {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-5) var(--s-6) var(--s-4);
  border-bottom: 1px solid var(--line-subtle);
}
.atlas-sheet__head > div { flex: 1 1 auto; min-width: 0; }
.atlas-sheet__title, .atlas-sheet__head h2 { margin: 0; font: 600 18px/24px var(--font-sans); letter-spacing: var(--track-section); color: var(--text); }
.atlas-sheet__desc, .atlas-sheet__head p { margin: 2px 0 0; font: var(--type-meta); color: var(--text-2); }
.atlas-sheet__close { margin: -6px -8px 0 0; }
.atlas-sheet__close > svg { width: var(--icon-lg); height: var(--icon-lg); }
.atlas-sheet__body {
  display: grid;
  flex: 1 1 auto;
  align-content: start;
  gap: var(--s-5);
  min-height: 0;
  padding: var(--s-5) var(--s-6) var(--s-6);
  overflow: auto;
}
.atlas-sheet__foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-6);
  border-top: 1px solid var(--line);
  background: var(--surface);
}
.atlas-sheet__foot-start { margin-right: auto; }
@keyframes atlas-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes atlas-dialog-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes atlas-sheet-in { from { opacity: 0; transform: translateX(24px); } to { opacity: 1; transform: none; } }
@keyframes atlas-sheet-up { from { opacity: 0; transform: translateY(24px); } to { opacity: 1; transform: none; } }
@media (max-width: 767px) {
  .atlas-sheet, .atlas-sheet--wide {
    top: auto;
    right: 0;
    bottom: 0;
    left: 0;
    width: auto;
    max-height: calc(100% - 12px);
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    animation-name: atlas-sheet-up;
  }
  /* A sheet that is a whole screen on phones (recipe detail and editor). */
  .atlas-sheet--full-phone { top: 0; max-height: none; border-radius: 0; }
  .atlas-sheet--full-phone .atlas-sheet__grabber { display: none; }
  .atlas-sheet__grabber { display: block; width: 36px; height: 4px; margin: 8px auto 0; border-radius: 2px; background: var(--line-strong); flex: none; }
  .atlas-sheet__head, .atlas-sheet__body { padding-left: var(--s-4); padding-right: var(--s-4); }
  .atlas-sheet__foot { padding: var(--s-3) var(--s-4) calc(var(--s-3) + env(safe-area-inset-bottom)); }
  .atlas-sheet__foot > .atlas-btn, .atlas-dialog__foot > .atlas-btn { flex: 1 1 0; min-width: max-content; }
  /* Equal-width buttons while their labels fit; a label that doesn't fit
     moves its button to a second row instead of spilling past its border. */
  .atlas-sheet__foot { flex-wrap: wrap; }
}

/* ==========================================================================
   6.19 Popover, menu, tooltip
   ========================================================================== */
.atlas-menu,
.atlas-popover {
  z-index: var(--z-overlay);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: var(--surface);
  box-shadow: var(--shadow-pop);
  color: var(--text);
  animation: atlas-pop-in var(--dur-2) var(--ease-out);
}
.atlas-menu { display: grid; gap: 1px; min-width: 200px; max-width: 320px; margin: 0; padding: var(--s-2); list-style: none; }
.atlas-popover { max-width: 360px; padding: var(--s-4); }
.atlas-menu__item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  height: 36px;
  margin: 0;
  padding: 0 10px;
  border: 0;
  border-radius: var(--r-md);
  background: transparent;
  color: var(--text);
  font: var(--type-body);
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.atlas-menu__item > svg { width: var(--icon-sm); height: var(--icon-sm); color: var(--text-2); flex: none; }
.atlas-menu__item:is(:hover, :focus-visible, [aria-selected="true"], .is-active) { background: var(--bg-muted); outline: none; text-decoration: none; }
.atlas-menu__item[aria-checked="true"]::after { content: ''; width: 8px; height: 4px; margin-left: auto; border-left: 2px solid var(--accent); border-bottom: 2px solid var(--accent); transform: rotate(-45deg); }
.atlas-menu__item--danger, .atlas-menu__item--danger > svg { color: var(--danger); }
.atlas-menu__item:disabled, .atlas-menu__item[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.atlas-menu__sep { height: 1px; margin: 6px -8px; background: var(--line); border: 0; }
.atlas-menu__label { padding: 8px 10px 4px; font: var(--type-caption); font-weight: 500; color: var(--text-3); }
@keyframes atlas-pop-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@media (pointer: coarse) { .atlas-menu__item { height: var(--touch); } }

.atlas-tooltip,
[data-atlas-tooltip]::after {
  padding: 6px 8px;
  border-radius: var(--r-sm);
  background: var(--ink);
  color: #ffffff;
  font: var(--type-caption);
  white-space: nowrap;
  pointer-events: none;
}
.atlas-tooltip { position: fixed; z-index: var(--z-toast); max-width: 240px; padding: 4px 8px; font: 400 12px/16px var(--font-sans); }
/* CSS tooltip for icon buttons: the same text as aria-label, after 400 ms. */
[data-atlas-tooltip] { position: relative; }
/* A hidden tooltip is not rendered at all, so a trigger at the viewport edge
   never widens the page; it fades in after 400 ms. Triggers at the end (or
   start) of a row align it with data-atlas-tooltip-align="end" ("start"). */
[data-atlas-tooltip]::after {
  content: attr(data-atlas-tooltip);
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  z-index: var(--z-toast);
  display: none;
  max-width: min(280px, calc(100vw - 16px));
  transform: translateX(-50%);
}
[data-atlas-tooltip]:is(:hover, :focus-visible)::after {
  display: block;
  animation: atlas-tooltip-in var(--dur-1) var(--ease-out) 400ms both;
}
[data-atlas-tooltip][data-atlas-tooltip-align="end"]::after { left: auto; right: 0; transform: none; }
[data-atlas-tooltip][data-atlas-tooltip-align="start"]::after { left: 0; transform: none; }
@keyframes atlas-tooltip-in { from { opacity: 0; } to { opacity: 1; } }
@media (pointer: coarse) { [data-atlas-tooltip]::after { display: none; } }

/* ==========================================================================
   6.20 Avatar — .atlas-avatar (24 / 28 / 40 / 64)
   ========================================================================== */
.atlas-avatar {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  flex: none;
  border-radius: 50%;
  background: #e2e8f0;
  color: #334155;
  font: 600 12px/1 var(--font-sans);
  text-transform: uppercase;
}
.atlas-avatar > img { display: block; width: 100%; height: 100%; border-radius: 50%; object-fit: cover; object-position: center; }
.atlas-avatar--sm { width: 24px; height: 24px; }
.atlas-avatar--lg { width: 40px; height: 40px; font-size: 14px; }
.atlas-avatar--xl { width: 64px; height: 64px; font-size: 20px; }
.atlas-avatar--a { background: #e3e9f4; color: #2c4a78; }
.atlas-avatar--b { background: #efe5dc; color: #6b4424; }
.atlas-avatar--c { background: #e2efe8; color: #245a41; }
.atlas-avatar--d { background: #ece6f2; color: #54406e; }
.atlas-avatar__status {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--positive);
  box-shadow: 0 0 0 2px var(--surface);
}

/* ==========================================================================
   6.21 Empty state and 6.24 permission / unavailable — .atlas-empty
   ========================================================================== */
.atlas-empty {
  display: grid;
  justify-items: center;
  gap: var(--s-2);
  padding: var(--s-12) var(--s-6);
  text-align: center;
}
.atlas-empty__icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--s-2);
  border-radius: var(--r-lg);
  background: var(--neutral-soft);
  color: var(--text-2);
}
.atlas-empty__icon > svg { width: var(--icon-lg); height: var(--icon-lg); }
.atlas-empty__title, .atlas-empty h3 { margin: 0; font: var(--type-heading); color: var(--text); }
.atlas-empty__text, .atlas-empty p { max-width: 360px; margin: 0; font: var(--type-body); color: var(--text-2); }
.atlas-empty > .atlas-btn, .atlas-empty__actions { margin-top: var(--s-3); }
.atlas-empty--page { padding: var(--s-20) var(--s-6); }
.atlas-empty--inline { justify-items: start; padding: var(--s-6) 0; text-align: left; }

/* ==========================================================================
   6.22 Skeleton — .atlas-skel (appears after 150 ms; static with reduced motion)
   ========================================================================== */
.atlas-skel {
  display: block;
  height: 12px;
  border-radius: var(--r-xs);
  /* Warm ivory sweep over the cream track (ALCEDO), not a cool blue-white. */
  background: linear-gradient(90deg, var(--bg-muted) 0, var(--bg) 50%, var(--bg-muted) 100%);
  background-size: 200% 100%;
  opacity: 0;
  animation: atlas-skel-show 1ms linear 150ms forwards, atlas-shimmer 1.5s var(--ease-standard) 150ms infinite;
}
.atlas-skel--text { height: 12px; }
.atlas-skel--title { height: 24px; width: 40%; }
.atlas-skel--row { height: 48px; border-radius: 0; }
.atlas-skel--block { height: 96px; border-radius: var(--r-lg); }
.atlas-skel--circle { width: 28px; height: 28px; border-radius: 50%; }
/* Default page skeleton (AtlasShell.skeleton): the page header, a toolbar
   bar and list rows, drawn while a view waits for the shell data. */
.atlas-skel-page__sub { display: inline-block; width: 220px; max-width: 60%; vertical-align: middle; }
.atlas-skel-page__toolbar { margin: var(--s-5) 0 var(--s-3); }
.atlas-skel-page__toolbar > .atlas-skel { width: 280px; max-width: 100%; height: 36px; border-radius: var(--r-md); }
.atlas-skel-page__list { display: grid; overflow: hidden; }
.atlas-skel-page__list > .atlas-skel + .atlas-skel { border-top: 1px solid var(--line-subtle); }
@keyframes atlas-skel-show { to { opacity: 1; } }
@keyframes atlas-shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }

/* ==========================================================================
   6.23 Inline alert — .atlas-alert
   ========================================================================== */
.atlas-alert {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-lg);
  background: var(--neutral-soft);
  color: var(--text);
  font: var(--type-body);
}
.atlas-alert > svg, .atlas-alert > .icon { width: var(--icon-sm); height: var(--icon-sm); flex: none; margin-top: 2px; color: var(--text-2); }
.atlas-alert__content { flex: 1 1 auto; min-width: 0; }
.atlas-alert__title { margin: 0; font: 500 14px/20px var(--font-sans); color: var(--text); }
.atlas-alert__body { margin: 0; font: var(--type-body); color: var(--text-2); }
.atlas-alert__actions { display: flex; align-items: center; gap: var(--s-2); flex: none; margin-left: auto; }
.atlas-alert--warning { background: var(--warning-soft); }
.atlas-alert--warning > :is(svg, .icon) { color: var(--warning-icon); }
.atlas-alert--danger { background: var(--danger-soft); }
.atlas-alert--danger > :is(svg, .icon) { color: var(--danger); }
.atlas-alert--info { background: var(--accent-soft); }
.atlas-alert--info > :is(svg, .icon) { color: var(--accent); }
.atlas-alert--positive { background: var(--positive-soft); }
.atlas-alert--positive > :is(svg, .icon) { color: var(--positive); }
@media (max-width: 767px) { .atlas-alert { flex-wrap: wrap; } .atlas-alert__actions { margin-left: 28px; } }

/* ==========================================================================
   6.25 Toast — .atlas-toast in .atlas-toast-region (AtlasShell.toast)
   ========================================================================== */
.atlas-toast-region {
  position: fixed;
  left: 50%;
  bottom: 24px;
  z-index: var(--z-toast);
  display: grid;
  justify-items: center;
  gap: var(--s-2);
  width: max-content;
  max-width: calc(100vw - 32px);
  transform: translateX(-50%);
  pointer-events: none;
}
.atlas-toast {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  min-height: 44px;
  max-width: 100%;
  padding: 8px 8px 8px 14px;
  border-radius: var(--r-lg);
  background: var(--ink);
  color: #ffffff;
  box-shadow: var(--shadow-pop);
  font: 400 14px/20px var(--font-sans);
  pointer-events: auto;
  animation: atlas-toast-in var(--dur-2) var(--ease-out) both;
}
.atlas-toast:not(:has(.atlas-toast__action)) { padding-right: 16px; }
.atlas-toast > svg { width: var(--icon-sm); height: var(--icon-sm); flex: none; color: #7fd1a8; }
.atlas-toast--info > svg { color: #9cc3ff; }
.atlas-toast--warning > svg { color: #f5c46b; }
.atlas-toast__text { min-width: 0; }
.atlas-toast__action, .atlas-toast button {
  height: 32px;
  padding: 0 10px;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: #9cc3ff;
  font: 500 14px/20px var(--font-sans);
  white-space: nowrap;
  cursor: pointer;
}
.atlas-toast__action:hover, .atlas-toast button:hover { background: rgba(255, 255, 255, .08); }
.atlas-toast__action:focus-visible, .atlas-toast button:focus-visible { outline: 2px solid #9cc3ff; outline-offset: 0; }
/* Touch: the action (Undo) is a full 44 px target; the negative block margin
   takes it into the toast's own padding, so the toast keeps its height. */
@media (pointer: coarse) { .atlas-toast__action, .atlas-toast button { height: var(--touch); margin-block: -8px; } }
.atlas-toast.is-leaving { opacity: 0; transform: translateY(var(--move-sm)); transition: opacity calc(var(--motion-mid) * .7) var(--ease-in), transform calc(var(--motion-mid) * .7) var(--ease-in); }
@keyframes atlas-toast-in { from { opacity: 0; transform: translateY(var(--move-sm)); } to { opacity: 1; transform: none; } }
@media (max-width: 767px) {
  .atlas-toast-region { bottom: calc(var(--tabbar-h) + 12px + env(safe-area-inset-bottom)); }
}

/* ==========================================================================
   6.26 Workflow stepper — .atlas-steps
   ========================================================================== */
.atlas-steps {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-2);
  margin: 0;
  padding: 0;
  list-style: none;
  font: var(--type-label);
  color: var(--text-2);
}
/* Step labels never break inside a word (a sheet body wraps long user text
   anywhere; a step label is not user text). */
.atlas-steps { overflow-wrap: normal; }
.atlas-steps > li { display: flex; flex: none; align-items: center; gap: var(--s-2); white-space: nowrap; }
.atlas-steps .n {
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  flex: none;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  font: 600 12px/1 var(--font-sans);
}
.atlas-steps .is-done .n { border-color: var(--text); background: var(--text); color: #ffffff; }
.atlas-steps .is-done .n > svg { width: 12px; height: 12px; stroke-width: 2.5; }
.atlas-steps .is-current { color: var(--text); }
.atlas-steps .is-current .n { border-color: var(--accent); color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.atlas-steps .sep { width: 24px; height: 1px; flex: none; background: var(--line-strong); }
.atlas-steps-compact { display: none; }
.atlas-progress { height: 4px; overflow: hidden; border-radius: 2px; background: var(--bg-muted); }
.atlas-progress > i, .atlas-progress > span { display: block; height: 100%; border-radius: 2px; background: var(--accent); transition: width var(--dur-2) var(--ease-out); }
.atlas-progress--thin { height: 2px; }
@media (max-width: 767px) {
  .atlas-steps:has(+ .atlas-steps-compact) { display: none; }
  .atlas-steps-compact { display: grid; gap: var(--s-2); font: var(--type-label); color: var(--text); }
}
/* A stepper in a narrow container (an order sheet is 640 px): wrapped in
   .atlas-steps-wrap it shows the compact form whenever the container is
   narrower than a full row of labelled steps, instead of splitting labels
   or scrolling them out of view. */
.atlas-steps-wrap { container-type: inline-size; min-width: 0; }
@container (max-width: 719px) {
  .atlas-steps:has(+ .atlas-steps-compact) { display: none; }
  .atlas-steps-compact { display: grid; gap: var(--s-2); font: var(--type-label); color: var(--text); }
}

/* ==========================================================================
   6.27 File and photo upload — .atlas-upload
   ========================================================================== */
.atlas-upload {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-lg);
  background: var(--surface);
  color: var(--text-2);
  font: var(--type-meta);
  transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}
.atlas-upload.is-dragover { border-color: var(--accent); background: var(--accent-soft); }
.atlas-upload .thumb,
.atlas-upload__thumb {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  flex: none;
  overflow: hidden;
  border-radius: var(--r-md);
  background: var(--bg-subtle);
  color: var(--text-3);
}
.atlas-upload__thumb > img { width: 100%; height: 100%; object-fit: cover; }
.atlas-upload__body { flex: 1 1 auto; min-width: 0; }
.atlas-upload > .atlas-btn { flex: none; }   /* the text column wraps; the button keeps its label */
.atlas-upload__title { margin: 0; font: 500 14px/20px var(--font-sans); color: var(--text); overflow-wrap: anywhere; }
/* The hint under the title: a clear gap below the title, muted and smaller,
   and it wraps instead of pushing the control sideways. */
.atlas-upload__help { margin: var(--s-1) 0 0; font: var(--type-caption); color: var(--text-3); overflow-wrap: anywhere; }
.atlas-upload__error { margin: 2px 0 0; font: var(--type-caption); color: var(--danger); }
.atlas-upload .atlas-progress { margin-top: 6px; }
.atlas-upload--file { border-style: solid; border-color: var(--line); }

/* Inline spinner (buttons, AI progress) */
.atlas-spinner {
  display: inline-block;
  width: 16px;
  height: 16px;
  flex: none;
  border: 2px solid rgba(11, 15, 20, .14);
  border-top-color: var(--text-2);
  border-radius: 50%;
  animation: atlas-spin 700ms linear infinite;
}

/* ==========================================================================
   6.28 Disclosure — .atlas-disclosure ("Show details / Hide details")
   A wrapper holding a .atlas-disclosure__toggle (a button with aria-expanded)
   and a collapsible .atlas-disclosure__panel. The panel animates open/closed
   with a grid-template-rows 0fr→1fr + opacity transition — no measured height,
   so there is no content jump and rapid toggling just reverses the single
   interruptible transition. The panel wraps its content in one element (the
   overflow:hidden child) so the collapse clips cleanly. Open state is read from
   the toggle's aria-expanded, or a data-open / .is-open hook on the wrapper or
   the panel, so it works whatever the script toggles.
   ========================================================================== */
.atlas-disclosure { display: grid; gap: var(--s-2); min-width: 0; }
.atlas-disclosure__toggle {
  display: inline-flex;
  align-items: center;
  gap: var(--s-1);
  align-self: start;
  margin: 0;
  /* Keep the text-link look but give it a 44px touch target (a11y minimum). */
  min-height: var(--touch);
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--accent-text);
  font: var(--type-label);
  text-align: left;
  cursor: pointer;
}
.atlas-disclosure__toggle:hover { text-decoration: underline; text-underline-offset: 2px; }
.atlas-disclosure__toggle:focus-visible { outline: var(--focus-outline); outline-offset: var(--focus-offset); border-radius: var(--r-sm); }
/* The caret (a chevron svg) flips when the panel is open. */
.atlas-disclosure__toggle > svg { width: var(--icon-sm); height: var(--icon-sm); color: currentColor; transition: transform var(--motion-fast) var(--ease-out); }
.atlas-disclosure__toggle[aria-expanded="true"] > svg { transform: rotate(180deg); }
.atlas-disclosure__panel {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows var(--motion-mid) var(--ease-standard), opacity var(--motion-mid) var(--ease-standard);
}
.atlas-disclosure__panel > * { min-height: 0; overflow: hidden; }
.atlas-disclosure__toggle[aria-expanded="true"] + .atlas-disclosure__panel,
.atlas-disclosure__panel[data-open],
.atlas-disclosure[data-open] > .atlas-disclosure__panel,
.atlas-disclosure.is-open > .atlas-disclosure__panel {
  grid-template-rows: 1fr;
  opacity: 1;
}

/* Reduced motion: the skeleton shimmer is static and nothing slides. The
   movement tokens (--move-sm/--move-md) are already 0 here, so the button
   press/lift, toast slide, drawer and menu translate resolve to no movement
   automatically; below we additionally stop the looping/scaling animations and
   the disclosure/caret transitions while every open/hover/active state stays
   visible (colour, shadow, opacity and the open panel are unchanged). The
   mascot rules are intentionally untouched. */
@media (prefers-reduced-motion: reduce) {
  .atlas-skel { animation: atlas-skel-show 1ms linear 150ms forwards; }
  .atlas-loading-line::after { animation: none; left: 0; width: 100%; opacity: .6; }
  .atlas-tabs > :is(a, button, [role="tab"]):is([aria-current="page"], [aria-selected="true"], .is-active)::after { animation: none; transform: none; }
  .atlas-disclosure__panel { transition: none; }
  .atlas-disclosure__toggle > svg { transition: none; }
}
html.atlas-reduce-motion .atlas-skel { animation: atlas-skel-show 1ms linear 150ms forwards; }
html.atlas-reduce-motion .atlas-loading-line::after { animation: none; left: 0; width: 100%; opacity: .6; }
html.atlas-reduce-motion .atlas-tabs > :is(a, button, [role="tab"]):is([aria-current="page"], [aria-selected="true"], .is-active)::after { animation: none; transform: none; }
html.atlas-reduce-motion .atlas-disclosure__panel { transition: none; }
html.atlas-reduce-motion .atlas-disclosure__toggle > svg { transition: none; }
  /* ==========================================================================
     6.40 Atlas AI robot — .atlas-bot badge, .atlas-bot-live (atlas-bot.js)
     The assistant's face, never a replacement for the Atlas logo. The badge
     is one sprite of four frames (open · blink · sleep · happy) rendered from
     the 3D robot; data-state (set by the one state controller in atlas-bot.js)
     picks what it shows: idle blinks now and then, awake is a touch brighter,
     sleeping closes its eyes under a small Z · ZZ · ZZZ, thinking bobs and
     glows, listening and answering glow softly, attention holds a steady
     ring, error is dimmed (never red), success and hover smile. Animations run
     on the page clock (atlas-bot.js sets a negative delay), so a badge drawn
     again continues rather than restarts. Reduced motion (Atlas's setting or
     the system's): still frames; the state still shows (frame, ring, dimming).
     ========================================================================== */
  /* ALCEDO kingfisher mascot (replaces the robot sprite). The badge is the
     approved transparent bird as a *contained* background image: the head-and-
     upper-body crop for small badges, the full bird for the large live poster.
     Motion is restrained and whole-image only — gentle idle breathing on the
     live poster and a small listening tilt; no opacity blink, no warped beak or
     wing. Reduced motion keeps the bird completely static. The assistant state
     controller and every interaction are unchanged; transient states read
     through the accompanying status text (and a subtle teal ring), never by
     distorting the bird. */
  .atlas-bot {
    --atlas-bot-size: 20px;
    position: relative;
    display: inline-block;
    flex: none;
    width: var(--atlas-bot-size);
    height: var(--atlas-bot-size);
    background: transparent url('../atlas-bot/alcedo-mascot-head.png?v=20260930-glb2') center / contain no-repeat;
    vertical-align: middle;
    transition: transform var(--dur-2) var(--ease-out), filter var(--dur-2) var(--ease-out);
  }
  :is(a, button):hover > .atlas-bot { transform: translateY(-1px); }
  .atlas-bot[data-state="error"] { filter: saturate(.85); }
  /* The large live surface shows the FULL bird and carries the restrained
     motion: breathing at rest, a small tilt while listening. */
  .atlas-bot-live__poster {
    background-image: url('../atlas-bot/alcedo-mascot-poster.png?v=20260930-glb2');
    transform-origin: 50% 86%;
    animation: alcedo-bot-breathe 5.2s ease-in-out infinite;
  }
  .atlas-bot-live[data-framing="head"] .atlas-bot-live__poster {
    background-image: url('../atlas-bot/alcedo-mascot-head-glass.png?v=20260930-glb2');
  }
  .atlas-bot-live[data-state="listening"] > .atlas-bot-live__poster { animation: alcedo-bot-listen 3.6s ease-in-out infinite; }
  @keyframes alcedo-bot-breathe {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.025); }
  }
  @keyframes alcedo-bot-listen {
    0%, 100% { transform: rotate(0deg) scale(1.01); }
    50% { transform: rotate(-3deg) scale(1.02); }
  }
  /* 24 px or less (AtlasBot.html adds the class; the static nav and tab bar
     badges carry it): a tighter face, a matte visor and brighter eyes, so the
     robot does not read as a dark blob. */
  .atlas-bot--small { background-image: url('../atlas-bot/alcedo-mascot-head.png?v=20260930-glb2'); }

  /* Sleeping: Z, then ZZ, then ZZZ rising at the badge's top right, a fade and
     a pause, in CSS alone: one pseudo-element whose two text-shadow copies are
     the second and third Z, each a step higher. Its resting style is the
     reduced-motion look: a single still Z. Hovering the item (a wake trigger)
     hides it at once. */
  .atlas-bot::after {
    --atlas-bot-z: rgba(51, 65, 85, .78);
    content: none;
    position: absolute;
    left: calc(100% - var(--atlas-bot-size) * .15);
    bottom: calc(100% - var(--atlas-bot-size) * .45);
    color: var(--atlas-bot-z);
    font-family: var(--font-sans);
    font-size: calc(var(--atlas-bot-size) * .3);
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    text-shadow: calc(var(--atlas-bot-size) * .14) calc(var(--atlas-bot-size) * -.3) 0 transparent, calc(var(--atlas-bot-size) * .28) calc(var(--atlas-bot-size) * -.6) 0 transparent;
    opacity: .8;
    pointer-events: none;
  }
  .atlas-bot[data-state="sleeping"]::after {
    content: 'Z';
    /* Starts at one Z whenever the robot falls asleep. */
    animation: atlas-bot-z-reveal 6s step-end infinite, atlas-bot-z-fade 6s ease-in-out infinite;
  }
  :is(a, button):hover > .atlas-bot::after,
  .atlas-bot-live > .atlas-bot.atlas-bot-live__poster::after { content: none; }
  @keyframes atlas-bot-z-reveal {
    0% { text-shadow: calc(var(--atlas-bot-size) * .14) calc(var(--atlas-bot-size) * -.3) 0 transparent, calc(var(--atlas-bot-size) * .28) calc(var(--atlas-bot-size) * -.6) 0 transparent; }
    20% { text-shadow: calc(var(--atlas-bot-size) * .14) calc(var(--atlas-bot-size) * -.3) 0 var(--atlas-bot-z), calc(var(--atlas-bot-size) * .28) calc(var(--atlas-bot-size) * -.6) 0 transparent; }
    40% { text-shadow: calc(var(--atlas-bot-size) * .14) calc(var(--atlas-bot-size) * -.3) 0 var(--atlas-bot-z), calc(var(--atlas-bot-size) * .28) calc(var(--atlas-bot-size) * -.6) 0 var(--atlas-bot-z); }
  }
  @keyframes atlas-bot-z-fade {
    0% { opacity: 0; translate: 0 1px; }
    6% { opacity: .8; translate: 0 0; }
    62% { opacity: .8; translate: 0 -1px; }
    74% { opacity: 0; translate: 0 -2px; }
    100% { opacity: 0; translate: 0 -2px; }
  }
  html.atlas-reduce-motion .atlas-bot { animation: none; transition: none; }
  html.atlas-reduce-motion .atlas-bot[data-state]::after { animation: none; }
  html.atlas-reduce-motion :is(a, button):hover > .atlas-bot { transform: none; }
  /* Still, the busy states keep a look of their own (never shown by movement
     alone): listening an inner blue ring, thinking the tilted head of its
     movement with a faint ring, answering a soft outer ring. */
  /* Kingfisher: with reduced motion the bird stays completely still; transient
     states (listening/thinking/answering) are conveyed by the status text, not
     by a ring or a tilt. */
  /* .atlas-bot[data-state] is as specific as the state rules above, so the
     system setting wins over their animations too (a plain .atlas-bot lost
     to them: thinking, listening and answering kept moving). */
  @media (prefers-reduced-motion: reduce) {
    .atlas-bot, .atlas-bot[data-state] { animation: none; transition: none; }
    :is(a, button):hover > .atlas-bot { transform: none; }
    .atlas-bot[data-state]::after { animation: none; }
    /* Kingfisher: still bird under reduced motion; state is shown in text. */
  }

  /* The interactive robot: the badge is its poster until the 3D scene draws.
     The 3D scene draws the full robot's contact shadow itself. */
  .atlas-bot-live {
    --atlas-bot-live-size: 160px;
    position: relative;
    display: grid;
    place-items: center;
    width: var(--atlas-bot-live-size);
    height: var(--atlas-bot-live-size);
    container-type: size;
    touch-action: manipulation;
  }
  .atlas-bot-live__canvas { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; transition: opacity var(--dur-3) var(--ease-out); cursor: pointer; -webkit-tap-highlight-color: transparent; }
  .atlas-bot-live.is-live .atlas-bot-live__canvas { opacity: 1; }
  .atlas-bot-live.is-live .atlas-bot-live__poster { visibility: hidden; }
  .atlas-bot-live.is-static .atlas-bot-live__canvas { display: none; }
  /* The poster is the head at 72% of the robot's box, whatever size the box
     is given (a phone or a short screen draws the robot smaller). */
  .atlas-bot-live > .atlas-bot-live__poster { width: 72%; height: 72%; }

  /* Sleeping: Z · ZZ · ZZZ in the robot's own top-right corner (inside its
     box, so it never reaches other content), in the display face, Midnight at
     low opacity; each letter a little larger and higher. Hidden the moment
     the robot wakes. Resting style = reduced motion: one still Z. */
  .atlas-bot-z { display: none; }
  .atlas-bot-live[data-state="sleeping"] > .atlas-bot-z {
    position: absolute;
    top: 1%;
    right: 1%;
    display: block;
    width: 22%;
    height: 21%;
    color: rgba(51, 65, 85, .7);
    font-family: var(--font-sans);
    font-weight: 500;
    line-height: 1;
    pointer-events: none;
  }
  .atlas-bot-z > i { position: absolute; font-style: normal; letter-spacing: .02em; opacity: 0; }
  .atlas-bot-z > i:nth-child(1) { left: 8%; bottom: 0; font-size: 5.5cqmin; opacity: .7; }
  .atlas-bot-z > i:nth-child(2) { left: 38%; bottom: 26%; font-size: 7.5cqmin; }
  .atlas-bot-z > i:nth-child(3) { left: 68%; bottom: 50%; font-size: 9.5cqmin; }
  .atlas-bot-live[data-state="sleeping"] > .atlas-bot-z > i { animation: 6s ease-in-out infinite; }
  .atlas-bot-live[data-state="sleeping"] > .atlas-bot-z > i:nth-child(1) { animation-name: atlas-bot-z1; }
  .atlas-bot-live[data-state="sleeping"] > .atlas-bot-z > i:nth-child(2) { animation-name: atlas-bot-z2; }
  .atlas-bot-live[data-state="sleeping"] > .atlas-bot-z > i:nth-child(3) { animation-name: atlas-bot-z3; }
  @keyframes atlas-bot-z1 {
    0% { opacity: 0; translate: 0 2px; }
    6% { opacity: .75; translate: 0 0; }
    62% { opacity: .75; translate: 0 -1px; }
    74% { opacity: 0; translate: 0 -3px; }
    100% { opacity: 0; translate: 0 -3px; }
  }
  @keyframes atlas-bot-z2 {
    0%, 18% { opacity: 0; translate: 0 2px; }
    24% { opacity: .75; translate: 0 0; }
    62% { opacity: .75; translate: 0 -1px; }
    74% { opacity: 0; translate: 0 -3px; }
    100% { opacity: 0; translate: 0 -3px; }
  }
  @keyframes atlas-bot-z3 {
    0%, 36% { opacity: 0; translate: 0 2px; }
    42% { opacity: .75; translate: 0 0; }
    62% { opacity: .75; translate: 0 -1px; }
    74% { opacity: 0; translate: 0 -3px; }
    100% { opacity: 0; translate: 0 -3px; }
  }
  html.atlas-reduce-motion .atlas-bot-live[data-state] > .atlas-bot-z > i { animation: none; }
  @media (prefers-reduced-motion: reduce) {
    .atlas-bot-live[data-state] > .atlas-bot-z > i:nth-child(n) { animation: none; }
  }
}
