/* ═══════════════════════════════════════════════════════════════════
   Ákotí theme bridge
   The vendored components hardcode their own palette and use no custom
   properties, so there is nothing to redefine. This file retints them to
   tokens.css. Never edit a file under static/akoti/; change it here.
   Left alone deliberately: the asymmetric brick radii and the inset
   "engrave" shadow. Those are the Ákotí signature. A brick radius is
   never replaced by a symmetric one. Must load after every akoti/*.css
   and before app-extras.css.
   ═══════════════════════════════════════════════════════════════════ */
/* ── Buttons: slate is the solid tone; navy would read as a 2nd brand ── */
.akoti-btn {
  border-color: var(--line);
  color: var(--ink);
  min-height: var(--tap);              /* touch target, not decoration */
  font-size: 14px;
}
@media (min-width: 700px) {
  .akoti-btn { min-height: 0; font-size: 13px; }
  .akoti-btn.lg, .akoti-btn.xl { min-height: var(--tap); }
}
.akoti-btn:focus-visible { outline-color: var(--blue); }
.akoti-btn:hover { box-shadow: 0 2px 8px rgba(61, 74, 92, .1); }

.akoti-btn.primary {
  background: var(--slate);
  border-color: transparent;
  color: #fff;
  box-shadow: 0 2px 6px rgba(61, 74, 92, .18);
}
.akoti-btn.primary:hover { background: #33404f; }

.akoti-btn.secondary {
  background: var(--blue-wash);
  border-color: rgba(127, 178, 221, .5);
  color: var(--blue-deep);
}
.akoti-btn.secondary:hover { background: #dceaf7; }

.akoti-btn.ghost { border-color: var(--line); color: var(--ink); }
.akoti-btn.ghost:hover { background: var(--surface-2); }
.akoti-btn.link { color: var(--blue-deep); }
.akoti-btn.success { background: var(--ok); border-color: transparent; }
.akoti-btn.danger { background: var(--alert); border-color: transparent; }
.akoti-btn.warning { background: var(--warn); border-color: transparent; }
.akoti-btn.bronze { background: var(--bronze); border-color: transparent; }

/* ── Cards: elevation is tone ──────────────────────────────────────
   Depth is the tonal ramp, not a border plus a drop shadow on every
   surface. Shadows are kept for what genuinely floats — the palette, the
   coach panel, the modal. The brick radius does not change, at any step. */
.akoti-card {
  background: var(--surface-base);
  border-color: var(--line-soft);
  border-radius: var(--brick);
  box-shadow: none;
}
.akoti-card.tone-high { background: var(--surface-high); }
.akoti-card.tone-highest { background: var(--surface-highest); border-color: var(--line); }
/* Recessed: a well the page sinks into — what the engrave is for. */
.akoti-card.tone-low { background: var(--surface-low); box-shadow: var(--engrave); }
.akoti-card.tone-lowest { background: var(--surface-lowest); box-shadow: var(--engrave); }

/* Tinted panels use the container roles, not a per-component wash.
   Verified at 7.68, 6.29 and 6.39 to one. */
.akoti-card.tone-primary { background: var(--primary-container); color: var(--on-primary-container); border-color: rgba(127,178,221,.4); }
.akoti-card.tone-secondary { background: var(--secondary-container); color: var(--on-secondary-container); border-color: rgba(232,180,184,.5); }
.akoti-card.tone-tertiary { background: var(--tertiary-container); color: var(--on-tertiary-container); border-color: rgba(205,127,50,.28); }
.akoti-card.tone-primary .akoti-card-title { color: var(--on-primary-container); }
.akoti-card.tone-secondary .akoti-card-title { color: var(--on-secondary-container); }
.akoti-card.tone-tertiary .akoti-card-title { color: var(--on-tertiary-container); }

/* Ink pages: cards are paper, not tone. */
body.mode-ink .akoti-card { background: var(--paper); border-color: var(--line-soft); box-shadow: none; }
body.mode-ink .akoti-input, body.mode-ink .akoti-textarea { background: var(--paper-sunk); }
@media (hover: hover) {
  .akoti-card:hover { border-radius: var(--brick-flip); }
  .akoti-card-flat:hover { border-radius: var(--brick); }
}
.akoti-card-title { font-family: var(--font-display); color: var(--ink); }
.akoti-card-subtitle, .akoti-card-body { color: var(--muted); }
.akoti-card-body { color: var(--ink); }
.akoti-card-action { color: var(--blue-deep); }
.akoti-card-action:hover { color: var(--pink-deep); }
.akoti-card-footer { border-top-color: var(--line-soft); }
.akoti-card-flat { background: var(--surface-low); box-shadow: none; }
.akoti-card-bordered { background: var(--surface-highest); border-color: var(--line); }
/* Elevated keeps a shadow: it is the one variant claiming to be off the page. */
.akoti-card-elevated { background: var(--surface-highest); box-shadow: 0 6px 22px rgba(61, 74, 92, .10); }
.akoti-card-clickable:hover { border-color: var(--blue); }

.akoti-card-primary { background: var(--slate); border-color: transparent; }
.akoti-card-primary .akoti-card-action { color: var(--blue); }
.akoti-card-dark { background: var(--ink); border-color: transparent; }

/* ── Fields ───────────────────────────────────────────────────────
   The 16px floor is not style: iOS zooms the page below it. */

.akoti-label { color: var(--muted); }
.akoti-label .required { color: var(--alert); }

.akoti-input {
  font-size: 16px;
  min-height: var(--tap);
  background: var(--surface-2);
  border-color: var(--line);
  color: var(--ink);
  border-radius: var(--brick-sm);
  box-shadow: var(--engrave);
}
.akoti-input:hover { border-color: rgba(61, 74, 92, .24); }
.akoti-input:focus {
  border-color: var(--blue);
  border-radius: var(--brick-sm-flip);
  background: var(--surface);
  box-shadow: 0 0 0 3px rgba(127, 178, 221, .22), var(--engrave);
}
.akoti-input::placeholder { color: var(--faint); }
.akoti-input.sm { font-size: 16px; }        /* size shrinks padding, not text */
.akoti-input.lg { font-size: 16px; }
.akoti-textarea { min-height: 96px; line-height: 1.6; }

.akoti-input.error { border-color: var(--alert); }
.akoti-input.error:focus { border-color: var(--alert); box-shadow: 0 0 0 3px rgba(194, 91, 102, .18); }
.akoti-input.success { border-color: var(--ok); }
.akoti-input.success:focus { border-color: var(--ok); box-shadow: 0 0 0 3px rgba(47, 143, 118, .18); }
.akoti-field-hint { color: var(--muted); font-size: 12.5px; }
.akoti-field-error { color: var(--alert); }
.akoti-input:disabled { background: var(--surface-2); color: var(--faint); }
.akoti-input-icon .aki { color: var(--faint); }
.akoti-input-icon .akoti-input:focus ~ .aki,
.akoti-input-icon .akoti-input:focus + .aki { color: var(--blue-deep); }

/* The classes really are `akoti-check` / `akoti-check-mark`. There is no
   `.akoti-checkbox`; rules written against that name styled nothing. */
.akoti-select, select.akoti-input { background-color: var(--surface-2); }
.akoti-check input:checked + .akoti-check-mark,
.akoti-radio input:checked + .akoti-radio-mark {
  background: var(--slate); border-color: var(--slate);
}
.akoti-switch input:checked + .akoti-switch-track { background: var(--blue-deep); }

/* ── Badges and tags ───────────────────────────────────────────────── */

.akoti-badge { background: var(--slate); }
.akoti-badge.primary { background: var(--slate); }
.akoti-badge.info { background: var(--blue-wash); color: var(--blue-deep); }
.akoti-badge.success { background: var(--ok-wash); color: var(--ok); }
.akoti-badge.warning { background: var(--warn-wash); color: var(--warn); }
.akoti-badge.danger { background: var(--alert-wash); color: var(--alert); }
.akoti-badge.muted { background: var(--surface-2); color: var(--muted); }
.akoti-badge.bronze { background: #fbf1e6; color: #8b5e20; }
.akoti-badge.outline.primary, .akoti-badge.outline.info { color: var(--blue-deep); }
.akoti-badge.outline.success { color: var(--ok); }
.akoti-badge.outline.warning { color: var(--warn); }
.akoti-badge.outline.danger { color: var(--alert); }
.akoti-badge.outline.muted { color: var(--muted); }

.akoti-tag { background: var(--surface-2); color: var(--ink); border-color: var(--line-soft); }
.akoti-tag:hover { background: var(--blue-wash); }
.akoti-tag.primary { background: var(--blue-wash); border-color: rgba(127,178,221,.5); color: var(--blue-deep); }
.akoti-tag.success { background: var(--ok-wash); border-color: rgba(47,143,118,.35); color: var(--ok); }
.akoti-tag.warning { background: var(--warn-wash); border-color: rgba(192,127,46,.35); color: var(--warn); }
.akoti-tag.danger { background: var(--alert-wash); border-color: rgba(194,91,102,.35); color: var(--alert); }
.akoti-tag-remove:hover { background: var(--alert); }

.akoti-dot.primary { background: var(--slate); }
.akoti-dot.info { background: var(--blue-deep); }
.akoti-dot.success { background: var(--ok); }
.akoti-dot.warning { background: var(--warn); }
.akoti-dot.danger { background: var(--alert); }
.akoti-status { color: var(--muted); }

/* ── Lists ─────────────────────────────────────────────────────────── */

.akoti-list-item { border-bottom-color: var(--line-soft); color: var(--ink); }
.akoti-list-item.akoti-list-clickable { min-height: var(--tap); }
.akoti-list-item.akoti-list-clickable:hover { background: var(--blue-wash); }
.akoti-list-title { color: var(--ink); font-weight: 700; }
.akoti-list-desc, .akoti-list-meta { color: var(--muted); }
.akoti-list-item > .aki { color: var(--faint); }
.akoti-list-bordered .akoti-list-item { border-color: var(--line); box-shadow: var(--engrave); }
.akoti-list-bordered .akoti-list-item:hover { border-color: var(--blue); }
.akoti-list-striped .akoti-list-item:nth-child(even) { background: var(--surface-2); }
.akoti-dl dt { color: var(--muted); }
.akoti-dl dd { color: var(--ink); }

/* ── Empty states, stats, alerts, progress ─────────────────────────── */

.akoti-empty-icon { background: var(--surface-2); color: var(--faint); }
.akoti-empty-title { font-family: var(--font-display); color: var(--ink); }
.akoti-empty-desc { color: var(--muted); }
.akoti-empty.akoti-empty-card {
  background: var(--surface-2); border-color: var(--line); border-radius: var(--brick);
}

.akoti-stat { background: var(--surface-base); border-color: var(--line-soft); border-radius: var(--brick); box-shadow: none; }
.akoti-stat-icon { background: var(--blue-wash); color: var(--blue-deep); }
.akoti-stat-icon.blue { background: var(--blue-wash); color: var(--blue-deep); }
.akoti-stat-icon.green { background: var(--ok-wash); color: var(--ok); }
.akoti-stat-icon.amber { background: var(--warn-wash); color: var(--warn); }
.akoti-stat-icon.red { background: var(--alert-wash); color: var(--alert); }
.akoti-stat-icon.purple { background: var(--pink-wash); color: var(--pink-deep); }  /* no purple in this app */
.akoti-stat-icon.bronze { background: #fbf1e6; color: #8b5e20; }
.akoti-stat-label { color: var(--muted); }
/* Numbers are display-face, large and tight. Fraunces ships as static
   instances, so 900 is the heaviest weight that loads. */
.akoti-stat-value {
  font-family: var(--font-display); color: var(--ink);
  font-weight: 900; letter-spacing: -0.03em; line-height: 1.02;
  font-size: clamp(1.6rem, 5.5vw, 2.2rem);
  font-variant-numeric: tabular-nums lining-nums;
}
.akoti-stat-trend.up { color: var(--ok); }
.akoti-stat-trend.down { color: var(--alert); }
.akoti-stat-trend.flat { color: var(--muted); }

.akoti-alert { border-radius: var(--brick-sm); }
.akoti-alert.info { background: var(--blue-wash); border-color: rgba(127,178,221,.5); color: var(--blue-deep); }
.akoti-alert.success { background: var(--ok-wash); border-color: rgba(47,143,118,.4); color: #1f6b57; }
.akoti-alert.warning { background: var(--warn-wash); border-color: rgba(192,127,46,.4); color: #8f5c1d; }
.akoti-alert.danger { background: var(--alert-wash); border-color: rgba(194,91,102,.4); color: #8d3944; }

.akoti-progress-bar, .akoti-progress > span, .akoti-progress-fill { background: var(--blue-deep); }
.akoti-divider { border-color: var(--line-soft); }
.akoti-avatar { background: var(--blue-wash); color: var(--blue-deep); }

/* ── Tabs, accordion, modal, tooltip, skeleton, markdown ───────────── */

/* v2 components use short prefixes — aka2 / akt2 / akm2. Rules written
   against .akoti-tabs-v2 matched nothing at all. */
.akt2-tab { color: var(--muted); }
.akt2-radio:checked + .akt2-tab { color: var(--ink); border-color: var(--blue); }
.akt2-badge { background: var(--blue-wash); color: var(--blue-deep); }

.aka2-trigger { color: var(--ink); min-height: var(--tap); }
.aka2-trigger:hover { background: var(--surface-2); }
.aka2-item { border-color: var(--line-soft); }
.aka2-label { font-weight: 600; }

.akm2::backdrop { background: rgba(34, 34, 42, .42); }
.akm2-title { font-family: var(--font-display); color: var(--ink); }
.akoti-tooltip::after { background: var(--ink); }
.akl-skeleton { background: linear-gradient(90deg, var(--surface-2), #eaeef3, var(--surface-2)); }
.akoti-md { color: var(--ink); font-family: var(--font-body); }
.akoti-md h1, .akoti-md h2, .akoti-md h3 { font-family: var(--font-display); }
.akoti-md a { color: var(--blue-deep); }
.akoti-md code { background: var(--surface-2); }
.akoti-md blockquote { border-left-color: var(--pink); background: var(--pink-wash); }

/* Icons inherit the surrounding text colour; only the sizes need a floor. */
.aki { color: inherit; }

/* ── Sidebar ───────────────────────────────────────────────────────
   The vendored file goes off-canvas in a max-width:768px block. This app
   breaks at 960px and carries no max-width queries, so the base below is
   off-canvas and a min-width:960px query puts it back in flow. Height is
   100svh so mobile chrome cannot hide the sidebar footer. */

.akoti-sidebar {
  position: fixed;
  left: 0;
  top: 0;
  bottom: 0;
  height: 100svh;
  z-index: 60;
  width: 264px;
  max-width: 84vw;
  transform: translateX(-100%);
  transition: transform .28s cubic-bezier(.4, 0, .2, 1);
  background: var(--slate);
  font-family: var(--font-body);
  padding-left: env(safe-area-inset-left);
  box-shadow: 2px 0 18px rgba(34, 34, 42, .18);
}
.akoti-sidebar.akoti-sb-open { transform: translateX(0); }

.akoti-sb-header { border-bottom-color: rgba(255, 255, 255, .1); gap: 10px; }
.akoti-sb-brand {
  font-family: var(--font-display); font-size: 1.05rem;
  display: inline-flex; align-items: center; gap: 9px;
  text-decoration: none; color: #fff;
}
.akoti-sb-toggle {
  width: var(--tap); height: var(--tap);
  border-radius: 10px 4px 10px 4px;
  font-size: 22px; line-height: 1;
}
.akoti-sb-nav { padding: 6px 8px 14px; }
/* .38/.62 white measured 2.30 and 3.56 against the sidebar's translucent
   fill. .78 clears 4.58 and still reads as secondary. */
.akoti-sb-section { color: rgba(255, 255, 255, .78); }
.akoti-sb-item { min-height: var(--tap); font-size: 14px; }
.akoti-sb-item.active {
  background: rgba(127, 178, 221, .2);
  color: #eaf3fb;
  box-shadow: inset 3px 0 0 var(--blue);
}
.akoti-sb-icon { display: inline-flex; align-items: center; justify-content: center; }
.akoti-sb-badge { background: var(--pink); color: var(--ink); }
.akoti-sb-footer {
  border-top-color: rgba(255, 255, 255, .1);
  padding-bottom: calc(12px + env(safe-area-inset-bottom));
}
.akoti-sb-user { font-size: 12.5px; color: rgba(255, 255, 255, .78); }

@media (min-width: 960px) {
  .akoti-sidebar {
    position: sticky;
    transform: none;
    max-width: none;
    box-shadow: 2px 0 12px rgba(34, 34, 42, .06);
  }
  .akoti-sb-toggle { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .akoti-sidebar { transition: none; }
}

/* ── Float-ai coach ────────────────────────────────────────────────
   The launcher clears the toast stack and the gesture bar. Its organic
   blob radius is Ákotí's, and it stays. */

.akf-trigger {
  bottom: calc(18px + env(safe-area-inset-bottom));
  right: 16px;
  width: var(--tap); height: var(--tap);
  background: linear-gradient(135deg, var(--blue), var(--pink));
  box-shadow: 0 4px 20px rgba(127, 178, 221, .4), inset 0 2px 4px rgba(255, 255, 255, .3);
}
.akf-trigger::before { background: linear-gradient(135deg, var(--pink), var(--blue)); }
.akf-trigger::after { border-color: rgba(127, 178, 221, .3); }
.akf-trigger-icon { color: var(--slate); font-family: var(--font-display); font-size: 19px; }
.akf-badge { background: var(--pink); }
@media (min-width: 700px) {
  .akf-trigger { bottom: 22px; right: 22px; width: 54px; height: 54px; }
  .akf-trigger-icon { font-size: 22px; }
}

.akf-panel {
  bottom: calc(78px + env(safe-area-inset-bottom));
  left: 12px; right: 12px; width: auto;
  height: min(520px, calc(100svh - 150px));
  background: var(--surface);
  border-radius: var(--brick);
  box-shadow: 0 12px 48px rgba(34, 34, 42, .16), 0 0 0 1px var(--line-soft), var(--engrave);
}
@media (min-width: 560px) {
  .akf-panel { left: auto; right: 22px; width: 372px; bottom: 88px; }
}
.akf-header { background: var(--surface-2); border-bottom-color: var(--line-soft); }
.akf-header::after { background: linear-gradient(90deg, var(--blue), var(--pink)); }
.akf-avatar { background: linear-gradient(135deg, var(--blue), var(--blue-wash)); color: var(--slate); }
.akf-header-title { font-family: var(--font-display); color: var(--ink); font-size: 14px; }
.akf-header-status { color: var(--muted); }
.akf-online-dot { background: var(--ok); }
.akf-header-btn { width: 34px; height: 34px; color: var(--muted); }
.akf-header-btn:hover { background: var(--blue-wash); color: var(--ink); }
.akf-welcome-icon { background: linear-gradient(135deg, var(--blue-wash), var(--pink-wash)); }
.akf-welcome h3 { font-family: var(--font-display); color: var(--ink); }
.akf-welcome p { color: var(--muted); font-size: 13.5px; }
.akf-msg-user .akf-msg-avatar { background: var(--pink); color: var(--ink); }
.akf-msg-ai .akf-msg-avatar { background: var(--blue); color: var(--slate); }
.akf-bubble { color: var(--ink); font-size: 14px; }
.akf-msg-user .akf-bubble { background: var(--pink-wash); border-color: rgba(232, 180, 184, .45); }
.akf-msg-ai .akf-bubble { background: var(--blue-wash); border-color: rgba(127, 178, 221, .35); }
.akf-bubble code { background: var(--surface-2); }
.akf-time { color: var(--faint); }
.akf-thinking-dot { background: var(--blue); }
.akf-thinking-dot:nth-child(2) { background: var(--pink); }
.akf-cursor { background: var(--blue-deep); }
.akf-input-bar { background: var(--surface-2); border-top-color: var(--line-soft); }
.akf-input {
  font-size: 16px;                     /* 16px floor, same reason as elsewhere */
  background: var(--surface); border-color: var(--line); color: var(--ink);
  min-height: var(--tap);
}
.akf-input:focus { border-color: var(--blue); }
.akf-input::placeholder { color: var(--faint); }
.akf-input:disabled { background: var(--surface-2); color: var(--faint); }
.akf-send { width: var(--tap); height: var(--tap); background: var(--slate); color: #fff; }
.akf-send:hover { background: #33404f; }
.akf-footer { color: var(--faint); border-top-color: var(--line-soft); }
.akf-footer span { color: var(--blue-deep); }
.akf-suggestion { color: var(--blue-deep); background: var(--blue-wash); border-color: rgba(127,178,221,.35); }
.akf-suggestion:hover { background: var(--blue); color: var(--slate); border-color: var(--blue); }
.akm-action-btn { color: var(--muted); }
.akm-action-btn.akm-active { background: var(--blue-wash); color: var(--blue-deep); border-color: rgba(127,178,221,.4); }

/* Ákotí's card footer is a nowrap flex row, which squashes anything wider
   than two buttons on a phone. This variant wraps instead at 360px. */
.akoti-card-footer.wrap { flex-wrap: wrap; row-gap: 8px; }

/* The Django-messages toast is an .akoti-card with no .akoti-card-body, so
   the padding a card gets from its body has to come from here. The hover
   radius flip is suppressed: a toast is not a target. */
.msg-tile.akoti-card { padding: 15px 16px; }
.msg-tile.akoti-card:hover { border-radius: var(--brick); }
@media (min-width: 700px) { .msg-tile.akoti-card { padding: 18px 20px; } }
