/* ==========================================================================
   DHI CCOps — wabi-sabi theme
   --------------------------------------------------------------------------
   Wabi-sabi is the beauty of things imperfect, impermanent and incomplete.
   Applied to an internal quality tool that is used to review recordings of
   people's work, it is not decoration — it is the right posture. This software
   passes judgement on human beings all day. The interface should feel quiet
   and unfinished rather than clinical and certain.

   What that means concretely, and why each choice was made:

     PAPER, NOT SCREEN    The page is warm off-white (#F4F2ED), not #FFFFFF.
                          Pure white on a backlit display is the colour of a
                          verdict. Paper is the colour of a draft.

     MA (間) — INTERVAL    Space is a material, not leftover. Generous padding
                          and line-height do more for comprehension in a
                          finding-dense screen than any border ever will.

     KANSO — RESTRAINT    One accent colour, no gradients on content, no
                          shadows except where depth carries meaning (drawer,
                          tooltip). Borders are hairlines in a warm grey that
                          recedes instead of framing.

     FUKINSEI — ASYMMETRY Panels carry one squared corner among three soft
                          ones, like a torn edge. It is deliberately slight:
                          enough to feel made rather than generated.

     TEXTURE              A near-invisible grain sits over the page. It is what
                          stops a large flat area reading as sterile. At 2.5%
                          opacity you do not see it; you only notice its
                          absence.

   Accessibility is not traded away for any of this. Every text/background pair
   below meets WCAG AA, status is never carried by colour alone (each .status
   has a glyph), focus rings are thick and always visible, and the whole theme
   respects prefers-reduced-motion and prefers-color-scheme.
   ========================================================================== */

:root {
  /* --- DHI core --- */
  --teal:        #0B6F69;   /* the brand */
  --teal-deep:   #075450;   /* pressed / hover */
  --teal-soft:   #E3EDEB;   /* wash behind headers and selected rows */
  --teal-line:   #BCD5D1;

  /* --- earth --- */
  --paper:       #F4F2ED;   /* the page */
  --card:        #FBFAF7;   /* raised surface */
  --ink:         #23302E;   /* body text        — 12.9:1 on paper */
  --mut:         #62706D;   /* secondary text   —  5.1:1 on paper */
  --bd:          #E2DED4;   /* hairline */
  --bd-strong:   #CFC9BB;

  /* --- signal. Muted earth pigments, not alert colours. --- */
  --good:        #3F6B4C;  --good-bg:  #EAF0E9;
  --warn:        #8A5A2B;  --warn-bg:  #F6EFE4;
  --crit:        #8C3A32;  --crit-bg:  #F6E9E7;

  --info-ink:    #4C5A57;   /* smallest text in the product; see .info */
  --on-teal:     #FFFFFF;   /* ink ON a teal fill — flips in dark mode,
                               because the dark-mode teal is a LIGHT colour */
  --focus:       #0B6F69;
  --gap:         18px;
  --radius:      12px;
  --fs:          15.5px;

  /* Washi grain. Inlined as a data URI so the page stays self-contained and
     the strict Content-Security-Policy (img-src 'self' data:) is satisfied. */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

[data-density="compact"] { --gap: 11px; --fs: 14px; --radius: 9px; }

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper:     #1A1E1D;   /* sumi ink */
    --card:      #232928;
    --ink:       #E7E3D9;   /* 12.4:1 on paper */
    --mut:       #9AA6A2;   /*  6.0:1 on paper */
    --bd:        #333B39;
    --bd-strong: #46504D;
    --teal:      #6FBDB5;   /* lifted so it passes AA on a dark ground */
    --teal-deep: #8FD3CB;
    --teal-soft: #1E3230;
    --teal-line: #2C4643;
    --good:      #8DBE97;  --good-bg: #1D2A20;
    --warn:      #D6A46B;  --warn-bg: #2C2418;
    --crit:      #E09189;  --crit-bg: #2E1D1B;
    --info-ink:  #AEB9B5;
    --on-teal:   #10201E;
    --focus:     #8FD3CB;
  }
}
:root[data-theme="dark"] {
  --paper:#1A1E1D; --card:#232928; --ink:#E7E3D9; --mut:#9AA6A2;
  --bd:#333B39; --bd-strong:#46504D;
  --teal:#6FBDB5; --teal-deep:#8FD3CB; --teal-soft:#1E3230; --teal-line:#2C4643;
  --good:#8DBE97; --good-bg:#1D2A20; --warn:#D6A46B; --warn-bg:#2C2418;
  --crit:#E09189; --crit-bg:#2E1D1B; --info-ink:#AEB9B5; --on-teal:#10201E; --focus:#8FD3CB;
}

/* -------------------------------------------------------------------------
   Base
   ------------------------------------------------------------------------- */
* { box-sizing: border-box; margin: 0; padding: 0; }
html { font-size: var(--fs); }

body {
  font-family: "Segoe UI", system-ui, -apple-system, sans-serif;
  background-color: var(--paper);
  background-image: var(--grain);
  background-size: 120px 120px;
  color: var(--ink);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
}
/* The grain must never make text muddy, so it is knocked almost all the way
   back. It reads as fibre in the paper, not as a pattern. */
body { background-blend-mode: multiply; }
@media (prefers-color-scheme: dark) { body { background-blend-mode: screen; } }
body::before {
  content: ""; position: fixed; inset: 0; pointer-events: none; z-index: 0;
  background: var(--grain); opacity: .025;
}
body > * { position: relative; z-index: 1; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition: none !important; animation: none !important;
    scroll-behavior: auto !important;
  }
}

:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 3px;
  border-radius: 3px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--teal); color: var(--on-teal); padding: 12px 20px;
  border-radius: 0 0 10px 0; font-weight: 600;
}
.skip:focus { left: 0; }

::selection { background: var(--teal-soft); color: var(--ink); }

/* Links keep their underline. Removing it and relying on colour alone fails
   WCAG 1.4.1 for anyone who cannot separate the hues, and inside a page this
   text-dense an unmarked link is genuinely hard to spot. */
a {
  color: var(--teal);
  text-decoration-thickness: 1px;
  text-underline-offset: 2px;
}
a:hover { color: var(--teal-deep); }
a.primary-action, a.btn, a.skip { text-decoration: none; }

/* -------------------------------------------------------------------------
   Header and navigation
   ------------------------------------------------------------------------- */
header {
  background: var(--card);
  border-bottom: 1px solid var(--bd);
  padding: 16px 26px;
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
}
header h1 {
  font-size: 1.08rem; font-weight: 600; color: var(--teal);
  letter-spacing: .012em;
  display: flex; align-items: center; gap: 11px;
}
header h1::before {                         /* the ensō, quietly */
  content: ""; width: 22px; height: 22px; flex: none;
  background: var(--teal); opacity: .9;
  -webkit-mask: url("/static/icons/mark-256.png") center/contain no-repeat;
  mask: url("/static/icons/mark-256.png") center/contain no-repeat;
}
header .tag { font-size: .8rem; color: var(--mut); font-style: italic; }
header .prefs { margin-left: auto; display: flex; gap: 9px; align-items: center; }
/* An author display rule beats the hidden attribute's UA stylesheet, so a
   `hidden` element laid out with flex stays on screen. That is how the owner
   preference controls remained visible to an ADMIN after being marked hidden.
   Applies to every element, not just .prefs, because the same trap catches any
   flex or grid container the moment someone hides it. */
[hidden] { display: none !important; }

nav[aria-label="Main"] {
  background: var(--card); border-bottom: 1px solid var(--bd);
  padding: 0 16px; display: flex; gap: 2px; overflow-x: auto;
}
nav button {
  background: none; border: none; padding: 13px 15px;
  font-size: .93rem; font-family: inherit; color: var(--mut);
  cursor: pointer; white-space: nowrap;
  border-bottom: 2px solid transparent;
  transition: color .18s ease, border-color .18s ease;
}
nav button:hover { color: var(--ink); }
nav button[aria-current="page"] {
  color: var(--teal); border-bottom-color: var(--teal); font-weight: 600;
}

main { max-width: 1140px; margin: 0 auto; padding: calc(var(--gap) * 1.7) var(--gap); }

h2 {
  font-size: 1.12rem; font-weight: 600; margin-bottom: var(--gap);
  letter-spacing: .01em;
}
h3 { font-size: .97rem; font-weight: 600; margin: var(--gap) 0 9px; }
h4 { font-size: .9rem; font-weight: 600; }

/* -------------------------------------------------------------------------
   Surfaces. One squared corner among three soft ones — the torn edge.
   ------------------------------------------------------------------------- */
.panel, .card, details, .box {
  background: var(--card);
  border: 1px solid var(--bd);
  border-radius: var(--radius) var(--radius) var(--radius) 3px;
}
.panel { padding: calc(var(--gap) * 1.15); margin-bottom: var(--gap); }

.cards {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(185px, 1fr));
  gap: var(--gap); margin-bottom: calc(var(--gap) * 1.4);
}
.card { padding: calc(var(--gap) * 1.05); }
.card .v {
  font-size: 2rem; font-weight: 650; color: var(--teal);
  font-variant-numeric: tabular-nums; line-height: 1.15;
}
.card .v.crit { color: var(--crit); }
.card .l {
  color: var(--mut); font-size: .84rem; margin-top: 3px;
  display: flex; align-items: center; gap: 6px;
}

details { margin-bottom: var(--gap); }
details summary {
  padding: 13px 17px; cursor: pointer; font-weight: 600;
  list-style-position: inside;
}
details summary:hover { color: var(--teal); }
details[open] summary { border-bottom: 1px solid var(--bd); }
details .inner { padding: 15px 17px; }

/* -------------------------------------------------------------------------
   Controls
   ------------------------------------------------------------------------- */
.primary-action, .btn.primary {
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--teal); color: var(--on-teal); border: none;
  border-radius: 10px 10px 10px 3px;
  padding: 14px 24px; font-size: .98rem; font-family: inherit;
  cursor: pointer; text-decoration: none; font-weight: 550;
  transition: background .18s ease;
}
.primary-action:hover, .btn.primary:hover { background: var(--teal-deep); }

.btn {
  background: transparent; color: var(--teal);
  border: 1.5px solid var(--teal-line); border-radius: 8px 8px 8px 2px;
  padding: 9px 16px; font-size: .89rem; font-family: inherit; cursor: pointer;
  transition: border-color .18s ease, background .18s ease;
}
.btn:hover:not(:disabled) { border-color: var(--teal); background: var(--teal-soft); }
.btn:disabled { opacity: .4; cursor: not-allowed; }
.btn.danger { color: var(--crit); border-color: var(--crit); }
.btn.danger:hover:not(:disabled) { background: var(--crit-bg); }

label { font-size: .84rem; font-weight: 600; display: block; margin-bottom: 5px; }
input[type=text], input[type=number], input[type=date], input[type=password],
textarea, select {
  border: 1px solid var(--bd-strong); border-radius: 8px;
  padding: 9px 11px; font-family: inherit; font-size: .9rem; width: 100%;
  background: var(--card); color: var(--ink);
}
input:focus-visible, textarea:focus-visible, select:focus-visible {
  border-color: var(--teal);
}

/* -------------------------------------------------------------------------
   Tables
   ------------------------------------------------------------------------- */
table { width: 100%; border-collapse: collapse; font-size: .89rem; }
caption {
  text-align: left; color: var(--mut); font-size: .84rem;
  padding-bottom: 8px; font-style: italic;
}
th {
  text-align: left; padding: 10px 11px;
  background: var(--teal-soft); color: var(--teal);
  font-weight: 600; position: sticky; top: 0;
}
td { padding: 10px 11px; border-bottom: 1px solid var(--bd); vertical-align: top; }
tr:last-child td { border-bottom: none; }
tr.rowlink { cursor: pointer; }
tr.rowlink:hover, tr.rowlink:focus-within { background: var(--teal-soft); }

/* Status is never colour alone — every variant carries a glyph and a word. */
.status {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .79rem; font-weight: 600; padding: 3px 11px;
  border-radius: 13px 13px 13px 3px; white-space: nowrap;
}
.status::before { font-weight: 700; }
.status.good    { background: var(--good-bg); color: var(--good); }
.status.good::before    { content: "✓"; }
.status.warn    { background: var(--warn-bg); color: var(--warn); }
.status.warn::before    { content: "!"; }
.status.crit    { background: var(--crit-bg); color: var(--crit); }
.status.crit::before    { content: "✕"; }
/* --mut on the teal tint measures 4.33:1 — just under AA for text this small,
   so the neutral chip uses the darker ink like .info does. */
.status.neutral { background: var(--teal-soft); color: var(--info-ink); }
.status.neutral::before { content: "·"; }

/* -------------------------------------------------------------------------
   Findings
   ------------------------------------------------------------------------- */
.finding {
  border-left: 3px solid var(--warn); background: var(--warn-bg);
  border-radius: 0 9px 9px 0; padding: 13px 16px; margin-bottom: 11px;
}
.finding.CRITICAL { border-left-color: var(--crit); background: var(--crit-bg); }
.finding.MAJOR    { border-left-color: var(--warn); }
.finding.good, .finding.practice {
  border-left-color: var(--good); background: var(--good-bg);
}
.finding.context  { border-left-color: var(--teal-line); background: var(--teal-soft); }
.finding h4 { margin-bottom: 5px; }
.finding .meta { font-size: .78rem; color: var(--mut); margin-bottom: 7px; }
.finding .quote {
  font-style: italic; color: var(--ink); opacity: .85;
  border-left: 2px solid var(--bd-strong); padding-left: 11px; margin: 7px 0;
}

/* -------------------------------------------------------------------------
   Rubric bars, transcript segments, audio
   ------------------------------------------------------------------------- */
.rubricbar {
  display: flex; align-items: center; gap: 10px;
  margin-bottom: 6px; font-size: .85rem;
}
.rubricbar .nm { min-width: 215px; }
.rubricbar .bar {
  flex: 1; height: 7px; background: var(--bd); border-radius: 4px; overflow: hidden;
}
.rubricbar .fill { height: 100%; background: var(--teal); }
.rubricbar .sc {
  min-width: 46px; text-align: right; font-weight: 600;
  font-variant-numeric: tabular-nums;
}

audio { width: 100%; margin: 10px 0; }
.speed button {
  border: 1px solid var(--bd-strong); background: var(--card); color: var(--ink);
  border-radius: 6px; padding: 5px 11px; margin-right: 5px;
  cursor: pointer; font-size: .84rem; font-family: inherit;
}
.speed button[aria-pressed="true"] {
  background: var(--teal); color: var(--on-teal); border-color: var(--teal);
}

.seg { padding: 7px 11px; border-radius: 7px; display: flex; gap: 11px; cursor: pointer; }
.seg:hover, .seg:focus-visible { background: var(--teal-soft); }
.seg.active { background: var(--teal-soft); box-shadow: inset 2px 0 0 var(--teal); }
.seg .t {
  color: var(--teal); font-weight: 600; font-size: .79rem;
  min-width: 52px; font-variant-numeric: tabular-nums;
}
/* Low-confidence lines are shown, not hidden — a reviewer needs to know the
   machine was unsure rather than be quietly given a cleaned-up transcript. */
.seg .lowconf, .lowconf { opacity: .5; font-style: italic; }

/* -------------------------------------------------------------------------
   Explainers
   ------------------------------------------------------------------------- */
/* The explainer glyph is the smallest text in the product and it sits on both
   --card and the tinted --teal-soft table headers. --mut clears AA on card but
   lands at 4.33:1 on the tint, so it gets its own slightly darker ink rather
   than darkening every muted label in the app. */
.info {
  display: inline-flex; align-items: center; justify-content: center;
  width: 19px; height: 19px; border-radius: 50%;
  border: 1.5px solid var(--bd-strong); background: none; color: var(--info-ink);
  font-size: .7rem; font-weight: 700; cursor: pointer;
  vertical-align: middle; flex: none; font-family: inherit;
}
.info:hover, .info:focus-visible { border-color: var(--teal); color: var(--teal); }
.explain {
  position: absolute; z-index: 120; max-width: 370px;
  background: #202B29; color: #F1EEE6;
  border-radius: 11px 11px 11px 3px; padding: 15px 17px;
  font-size: .85rem; line-height: 1.55;
  box-shadow: 0 10px 30px rgba(20, 30, 28, .3);
}
.explain h4 { font-size: .9rem; margin-bottom: 7px; color: #fff; }
.explain dl { display: grid; grid-template-columns: auto 1fr; gap: 3px 10px; }
.explain dt { color: #A8CBC6; font-weight: 600; white-space: nowrap; }
.explain dd { margin: 0; }
.explain .close {
  position: absolute; top: 6px; right: 9px; background: none; border: none;
  color: #C8D8D5; font-size: 1.05rem; cursor: pointer;
}

/* -------------------------------------------------------------------------
   Drawer
   ------------------------------------------------------------------------- */
.drawer {
  position: fixed; inset: 0; background: rgba(26, 30, 29, .5);
  display: none; z-index: 100; overflow-y: auto;
}
.drawer .inner {
  background: var(--paper); max-width: 1000px; margin: 26px auto;
  border-radius: 16px 16px 16px 4px; padding: 26px; position: relative;
  box-shadow: 0 18px 50px rgba(20, 30, 28, .22);
}
.drawer .close-drawer {
  position: absolute; top: 13px; right: 15px; font-size: 1.3rem;
  background: none; border: none; cursor: pointer; color: var(--mut); padding: 7px;
}
.drawer .close-drawer:hover { color: var(--ink); }

/* -------------------------------------------------------------------------
   Utility
   ------------------------------------------------------------------------- */
.mut { color: var(--mut); }
.sm  { font-size: .85rem; }
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--gap); }
@media (max-width: 860px) { .grid2 { grid-template-columns: 1fr; } }
[data-focusmode="on"] .hide-in-focus { display: none; }
.empty {
  color: var(--mut); padding: 22px; text-align: center; font-style: italic;
}
.note {
  background: var(--teal-soft); border-radius: 9px 9px 9px 2px;
  padding: 12px 15px; font-size: .87rem; margin: 10px 0;
}
.sub { color: var(--mut); font-size: .85rem; }

/* A quiet rule used to separate sections without drawing a hard line. */
.rule {
  height: 1px; background: linear-gradient(to right, var(--bd), transparent);
  border: none; margin: calc(var(--gap) * 1.4) 0;
}

/* -------------------------------------------------------------------------
   Bulk sessions
   ------------------------------------------------------------------------- */
.progress {
  height: 9px; background: var(--bd); border-radius: 5px;
  overflow: hidden; margin: 9px 0;
}
.progress .fill { height: 100%; background: var(--teal); transition: width .4s ease; }
.progress .fill.failed { background: var(--crit); }

.pill {
  display: inline-block; font-size: .74rem; font-weight: 600;
  padding: 2px 9px; border-radius: 11px 11px 11px 2px;
  background: var(--teal-soft); color: var(--teal);
}
.pill.HIGH   { background: var(--crit-bg); color: var(--crit); }
.pill.MEDIUM { background: var(--warn-bg); color: var(--warn); }
.pill.LOW    { background: var(--good-bg); color: var(--good); }

.sessionrow {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  padding: 13px 0; border-bottom: 1px solid var(--bd);
}
.sessionrow:last-child { border-bottom: none; }
.sessionrow .grow { flex: 1; min-width: 220px; }

/* The dropzone is the one place a dashed edge is right: it should look like a
   space waiting to be filled rather than a container that is already closed. */
.dropzone {
  border: 2px dashed var(--bd-strong); border-radius: var(--radius);
  padding: 34px 22px; text-align: center; color: var(--mut);
  background: var(--card); transition: border-color .2s ease, background .2s ease;
}
.dropzone.over { border-color: var(--teal); background: var(--teal-soft); color: var(--teal); }
