/* Account settings drawer + accessibility panel.
 *
 * EXTRACTED FROM index.html 2026-08-09. It lived inline in that one page, so the
 * investigator page could not show the drawer without a SECOND copy of it, and
 * two copies of a stylesheet always drift. The repo rule is one authoritative
 * layer, so the file moved rather than being duplicated.
 *
 * Dimensions and weights mirror the AcceleTrial implementation in
 * frontend/src/styles/shell.css. Keep them in step: the two products are meant
 * to look like one system.
 *
 * Any page that loads static/js/settings-drawer.js MUST load this too, or the
 * drawer renders unstyled. scripts/test_settings_contract.py asserts that pairing
 * so a new page cannot ship the script without the stylesheet.
 */

/* ── Account settings drawer (SPEC: Account Settings Menu, Bucket 1) ──
   Dimensions and weights mirror the AcceleTrial implementation in
   frontend/src/styles/shell.css. Keep them in step: the two products are
   meant to look like one. Slide-over from the right so the page stays
   visible behind it, which is the point of a drawer rather than a modal:
   a user adjusting text size needs to see the effect on real content. */
.ln-settings-btn {
  all: unset !important;
  cursor: pointer !important;
  color: rgba(13,43,69,0.55) !important;
  transition: color 140ms !important;
  padding: 5px 8px !important;
  border-radius: 6px !important;
  border: 1px solid rgba(13,43,69,0.14) !important;
  line-height: 1 !important;
  display: inline-flex !important;
  align-items: center !important;
}
.ln-settings-btn:hover { color: rgba(13,43,69,0.9) !important; background: rgba(13,43,69,0.05) !important; }
.settings-overlay {
  position: fixed; inset: 0; z-index: 2147483000;
  background: rgba(13,43,69,0.38);
  display: flex; justify-content: flex-end;
}
.settings-drawer {
  width: min(420px, 100vw); height: 100%;
  background: #fff; border-left: 1px solid #dae4ed;
  box-shadow: -12px 0 32px rgba(0,60,100,0.16);
  display: flex; flex-direction: column; outline: none;
  font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  animation: settings-slide-in 220ms cubic-bezier(0.16,1,0.3,1);
}
/* Anyone who asked the OS for less motion gets none. The Accessibility
   section adds an in-app override on top of this in Bucket 4. */
@media (prefers-reduced-motion: reduce) { .settings-drawer { animation: none; } }
@keyframes settings-slide-in {
  from { transform: translateX(16px); opacity: 0; }
  to   { transform: translateX(0);    opacity: 1; }
}
.settings-drawer__head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 18px 20px;
  background: linear-gradient(160deg, #163652 0%, #0d2b45 100%);
  border-bottom: 1px solid #dae4ed;
}
.settings-drawer__title {
  margin: 0; font-family: 'DM Serif Display', Georgia, serif;
  font-size: 1.15rem; font-weight: 400; color: #fff;
}
.settings-drawer__close {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; border-radius: 5px;
  border: 1px solid rgba(255,255,255,0.28);
  background: rgba(255,255,255,0.08); color: #fff; cursor: pointer;
}
.settings-drawer__close:hover { background: rgba(255,255,255,0.18); }
.settings-drawer__body { flex: 1; overflow-y: auto; padding: 16px; background: #f5f8fb; }
/* Every panel carries a visible border. House rule. */
.settings-section {
  background: #fff; border: 1px solid #dae4ed; border-radius: 5px;
  padding: 14px 16px; margin-bottom: 12px;
}
.settings-section:last-child { margin-bottom: 0; }
.settings-section__head { margin: 0; }
/* The heading IS the control. A heading that looks like navigation and does
   nothing when clicked is worse than no affordance at all. */
.settings-section__title {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; margin: 0; padding: 2px 0; cursor: pointer;
  background: none; border: 0; text-align: left;
  font: 700 0.7rem Inter, sans-serif;
  letter-spacing: 0.08em; text-transform: uppercase; color: #3a8ec7;
}
.settings-section__title:hover { color: #1a5a8a; }
.settings-section__title:focus-visible { outline: 2px solid #5dafe2; outline-offset: 3px; }
.settings-section__caret {
  width: 8px; height: 8px; flex: 0 0 auto;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform 140ms ease;
}
.settings-section__title[aria-expanded="true"] .settings-section__caret {
  transform: rotate(-135deg) translate(-2px, -2px);
}
.settings-section__body { margin-top: 10px; }
.settings-linklist { margin: 0 0 10px; padding: 0; list-style: none; }
.settings-linklist li { margin: 0 0 6px; }
.settings-link {
  display: block; padding: 8px 10px; border: 1px solid #d5e6f5; border-radius: 8px;
  color: #1a5a8a; background: #fff; text-decoration: none;
  font: 500 0.82rem Inter, sans-serif;
}
.settings-link:hover { background: #f0f7ff; border-color: #5dafe2; }
.settings-link:focus-visible { outline: 2px solid #5dafe2; outline-offset: 2px; }
.settings-section__body[hidden] { display: none; }
.settings-section__blurb { margin: 0; font: 400 0.82rem/1.55 Inter, sans-serif; color: #4a6478; }

/* ── Accessibility preferences (Bucket 4) ──────────────────────────
   Each rule keys off a data-* attribute that a11y.js sets on <html>
   before first paint. AcceleTrial implements the SAME nine against the
   SAME attribute names in its own stylesheet; settings-contract.json
   holds the two together. Absent attribute == default, so every rule
   below describes a state the user actually chose. */

/* Text size. rem-based type scales from the root, and the SPA's clamp()
   sizes are rem-based, so this reaches almost everything without touching
   a single component. */
html[data-text-scale="1.125"] { font-size: 112.5%; }
html[data-text-scale="1.25"]  { font-size: 125%; }
html[data-text-scale="1.5"]   { font-size: 150%; }

/* Reduced motion. The OS setting is honoured elsewhere via
   prefers-reduced-motion; this is the in-app override for someone whose OS
   is not set but who still wants things still. !important because it must
   beat per-component animation declarations. */
html[data-reduced-motion="on"],
html[data-reduced-motion="on"] *,
html[data-reduced-motion="on"] *::before,
html[data-reduced-motion="on"] *::after {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
  scroll-behavior: auto !important;
}

/* High contrast. Darkens body text and firms up borders rather than
   inverting anything: this is a light-mode clinical product and an
   inverted palette would be a different design, not an accessible one. */
html[data-high-contrast="on"] {
  --text-mid: #26405a;
  --text-soft: #4a6478;
  --border: #7d97ad;
}
html[data-high-contrast="on"] body { color: #06121f; }
html[data-high-contrast="on"] .panel,
html[data-high-contrast="on"] .settings-section,
html[data-high-contrast="on"] input,
html[data-high-contrast="on"] select,
html[data-high-contrast="on"] textarea { border-color: #7d97ad !important; }

/* Always-visible focus ring. :focus-visible hides the ring for mouse users,
   which is right by default and wrong for anyone who wants to see focus at
   all times. */
html[data-focus-always="on"] :focus {
  outline: 3px solid #1a5a8a !important;
  outline-offset: 2px !important;
}

/* Turn the custom cursor off and give the real one back. The site draws its
   own pointer and hides the system one; anybody who finds that unhelpful,
   or who has just watched it disappear behind a panel, can switch it off. */
html[data-custom-cursor-off="on"] .cursor-d,
html[data-custom-cursor-off="on"] .cursor-dot { display: none !important; }
html[data-custom-cursor-off="on"] body,
html[data-custom-cursor-off="on"] body * { cursor: auto !important; }
html[data-custom-cursor-off="on"] a,
html[data-custom-cursor-off="on"] button,
html[data-custom-cursor-off="on"] [role="button"],
html[data-custom-cursor-off="on"] summary { cursor: pointer !important; }

/* Underline links. Colour alone is not a sufficient cue (WCAG 1.4.1), and
   this product's links are blue text on white. */
html[data-underline-links="on"] a { text-decoration: underline !important; }

/* Table density. The trial and investigator tables are long; compact fits
   more rows on screen for people who scan them all day. */
html[data-table-density="compact"] td,
html[data-table-density="compact"] th { padding-top: .28rem !important; padding-bottom: .28rem !important; }

/* Larger targets. 44px is the WCAG 2.5.5 enhanced target size. */
html[data-large-targets="on"] button,
html[data-large-targets="on"] .ln-tab,
html[data-large-targets="on"] input[type="checkbox"],
html[data-large-targets="on"] input[type="radio"],
html[data-large-targets="on"] [role="button"] { min-height: 44px; min-width: 44px; }

/* Persistent toasts. A toast that vanishes on a timer is unreadable if you
   read slowly, use a screen reader, or looked away. The JS reads the same
   attribute to skip its auto-dismiss. */
html[data-toast-persist="on"] .toast { animation: none !important; opacity: 1 !important; }

.settings-a11y__row { padding: 10px 0; border-bottom: 1px solid #eaf3fa; }
.settings-a11y__row:last-of-type { border-bottom: 0; }
.settings-a11y__head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.settings-a11y__label { margin: 0; font: 600 0.82rem Inter, sans-serif; color: #0d2237; }
.settings-a11y__hint { margin: 4px 0 0; font: 400 0.75rem/1.45 Inter, sans-serif; color: #4a6478; }
.settings-a11y__check { width: 18px; height: 18px; flex: 0 0 auto; accent-color: #1a5a8a; cursor: pointer; }
.settings-a11y__choices { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.settings-a11y__choice {
  cursor: pointer; padding: 6px 12px; border: 1px solid #d5e6f5; border-radius: 8px;
  background: #fff; color: #0d2237; font: 500 0.78rem Inter, sans-serif;
}
.settings-a11y__choice:hover { background: #f0f7ff; border-color: #5dafe2; }
.settings-a11y__choice:focus-visible { outline: 2px solid #5dafe2; outline-offset: 2px; }
/* Selected state carries a check mark as well as colour (WCAG 1.4.1). */
.settings-a11y__choice--on { border-color: #1a5a8a; background: #eaf3fa; font-weight: 700; color: #1a5a8a; }
.settings-a11y__choice--on::after { content: " \2713"; }
.settings-a11y__reset {
  margin-top: 12px; cursor: pointer; padding: 7px 12px; border-radius: 8px;
  border: 1px solid #d5e6f5; background: #fff; color: #4a6478;
  font: 500 0.78rem Inter, sans-serif;
}
.settings-a11y__reset:hover { background: #f0f7ff; color: #1a5a8a; }

/* Account + Language (Bucket 3). Mirrors AcceleTrial's shell.css. */
.settings-kv-list { margin: 0 0 10px; padding: 0; }
.settings-kv {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px;
  padding: 7px 0; border-bottom: 1px solid #eaf3fa;
}
.settings-kv:last-child { border-bottom: 0; }
.settings-kv__k {
  margin: 0; flex: 0 0 auto;
  font: 600 0.72rem Inter, sans-serif; letter-spacing: .04em;
  text-transform: uppercase; color: #3a8ec7;
}
.settings-kv__v {
  margin: 0; min-width: 0; text-align: right; word-break: break-word;
  font: 400 0.84rem/1.45 Inter, sans-serif; color: #0d2237;
}
.settings-langlist {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 6px;
}
/* One column below 380px: two columns force "Bahasa Indonesia" to wrap or
   clip on the narrowest phones this product is actually opened on. */
@media (max-width: 380px) { .settings-langlist { grid-template-columns: 1fr; } }
.settings-lang {
  display: block; width: 100%; text-align: left; cursor: pointer;
  padding: 8px 10px; border: 1px solid #d5e6f5; border-radius: 8px;
  background: #fff; color: #0d2237; font: 400 0.82rem Inter, sans-serif;
  transition: background .12s ease, border-color .12s ease;
}
.settings-lang:hover { background: #f0f7ff; border-color: #5dafe2; }
.settings-lang:focus-visible { outline: 2px solid #5dafe2; outline-offset: 2px; }
.settings-lang--on {
  border-color: #1a5a8a; background: #eaf3fa; font-weight: 700; color: #1a5a8a;
}
/* The selected language must not be signalled by COLOUR ALONE (WCAG 1.4.1).
   A check mark carries it for anyone who cannot separate the two blues. */
.settings-lang--on::after { content: " \2713"; }
/* Settings drawer CONTENT (Bucket 2). Mirrors AcceleTrial's shell.css so the
   two products look like one. Keep them in step. */
.settings-body { margin-top: 10px; }
.settings-row { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.settings-row__label { font: 600 0.82rem Inter, sans-serif; color: #0d2237; }
.settings-pill {
  font: 700 0.62rem Inter, sans-serif; letter-spacing: .08em; text-transform: uppercase;
  padding: 3px 10px; border-radius: 999px;
  background: #f5f8fb; color: #4a6478; border: 1px solid #dae4ed;
}
.settings-pill--on { background: #d4f7df; color: #0d4f23; border-color: #9be0b3; }
.settings-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.settings-btn {
  padding: 7px 14px; border-radius: 5px; border: 1px solid transparent;
  background: linear-gradient(180deg, #5dafe2, #3a8ec7); color: #fff;
  font: 700 0.7rem Inter, sans-serif; letter-spacing: .05em; text-transform: uppercase; cursor: pointer;
}
.settings-btn:hover { filter: brightness(1.08); }
.settings-btn:disabled { opacity: .55; cursor: default; filter: none; }
.settings-btn--quiet { background: #fff; color: #1a5a8a; border-color: #dae4ed; }
.settings-form { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.settings-form label { font: 600 0.72rem Inter, sans-serif; color: #4a6478; }
.settings-form input {
  padding: 8px 10px; border: 1px solid #d5e6f5; border-radius: 5px;
  font: 400 0.85rem Inter, sans-serif; color: #0d2237;
}
.settings-form input:focus-visible { outline: 2px solid #5dafe2; outline-offset: 1px; }
.settings-msg { margin: 10px 0 0; font: 400 0.8rem/1.5 Inter, sans-serif; }
.settings-msg--err { color: #8a1a1a; }
.settings-msg--ok { color: #0d4f23; }
/* The key stays selectable and legible: it is the accessible path for anyone
   who cannot scan a QR, not a fallback. */
.settings-secret {
  display: block; margin: 8px 0; padding: 8px 10px;
  background: #f5f8fb; border: 1px solid #dae4ed; border-radius: 5px;
  font: 600 0.82rem/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; color: #0d2237;
  word-break: break-all; user-select: all;
}
.settings-qr { margin: 10px 0; }
