/* ============================================================================
   recite — reader sidebar. Owned by the sidebar phase.

   The aside that lists every มาตรา of the law next to the one being read.
   Notion-solid (taxcount studio): warm surfaces, 1px --trc-border, radius from
   the 4/6/8/10 ladder, hierarchy from tint not elevation, no gradients.
   Tokens only — never redefine :root, never edit app.css.

   Two shapes, one markup:
     ≥861px  a sticky column beside the text, its list scrolling on its own so
             a 1 700-มาตรา code never lengthens the page.
     ≤860px  a left drawer behind [data-side-toggle], over a backdrop.
   ========================================================================= */

/* ------------------------------------------------------------- the column */

.trc-reader-layout .trc-reader-wrap {
  /* index · statute · notes.
     The statute keeps the middle and its reading measure; the two asides are
     fixed so the measure never moves as you page between provisions. */
  display: grid;
  grid-template-columns: 260px minmax(0, 1fr) 320px;
  gap: var(--trc-s4);
  align-items: start;
  max-width: 1480px;
  margin: 0 auto;
}

.trc-reader-layout .trc-provision { min-width: 0; }

.trc-reader-side {
  position: sticky;
  top: calc(var(--trc-header-total) + var(--trc-s4));
  display: flex;
  flex-direction: column;
  /* The list scrolls inside this box; the page never grows with the law. */
  max-height: calc(100vh - var(--trc-header-total) - var(--trc-s6));
  max-height: calc(100dvh - var(--trc-header-total) - var(--trc-s6));
  min-height: 0;
  background: var(--trc-surface);
  border: var(--trc-border-w) solid var(--trc-border);
  border-radius: var(--trc-radius);
  box-shadow: var(--trc-shadow);
  overflow: hidden;
}

/* --------------------------------------------------------------- the head */

.trc-side-head {
  display: flex;
  align-items: baseline;
  gap: var(--trc-s2);
  padding: var(--trc-s3);
  border-bottom: var(--trc-border-w) solid var(--trc-border);
  background: var(--trc-surface-sunk);
}
.trc-side-head strong {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.trc-side-head a { color: var(--trc-text-2); white-space: nowrap; }
.trc-side-head a:hover { color: var(--trc-accent); }

.trc-side-search {
  padding: var(--trc-s2) var(--trc-s3);
  border-bottom: var(--trc-border-w) solid var(--trc-border);
}
.trc-side-search .trc-input { min-height: 30px; font-size: 13px; }
/* Safari's search cancel button steals width in a 300px column. */
.trc-side-search input[type="search"]::-webkit-search-decoration,
.trc-side-search input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
}

/* --------------------------------------------------------------- the list */

.trc-side-list {
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
  padding: var(--trc-s1) var(--trc-s2) var(--trc-s2);
  list-style: none;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.trc-side-item {
  display: flex;
  align-items: center;
  gap: var(--trc-s1);
  padding: 1px 2px 1px var(--trc-s2);
  border-radius: var(--trc-radius-sm);
  border-left: 2px solid transparent;
  /* Hundreds of rows: skip layout and paint for the ones off-screen. The
     intrinsic size keeps the scrollbar honest while they are skipped. */
  content-visibility: auto;
  contain-intrinsic-size: auto 32px;
}
.trc-side-item:hover { background: var(--trc-surface-hover); }

.trc-side-link {
  flex: 1 1 auto;
  min-width: 0;
  padding: 5px 0;
  color: var(--trc-text);
  font-size: 13px;
  line-height: 1.45;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.trc-side-link:hover { color: var(--trc-accent); text-decoration: none; }

/* "You are here" is position, not state. Brand red is reserved for
   deleted/overdue (tcs §13), so a red-tinted current row reads as an error
   sitting in a list of healthy provisions. Weight and a neutral tint carry it —
   which is also the house rule: make something pop with weight or contrast,
   not with colour. */
.trc-side-item.is-current {
  background: var(--trc-surface-active);
  border-left-color: var(--trc-text-2);
}
.trc-side-item.is-current .trc-side-link {
  color: var(--trc-text);
  font-weight: 600;
}

/* A มาตรา that no longer binds still has to be findable — greyed, not hidden.
   Only rows hydrated from /api/laws/{slug}/index carry a status. */
.trc-side-item[data-status="repealed"] .trc-side-link {
  color: var(--trc-text-3);
  text-decoration: line-through;
}
/* A repealed provision keeps its red even when current — there the colour IS
   the state, which is exactly what §13 reserves it for. */
.trc-side-item[data-status="repealed"].is-current .trc-side-link { color: var(--trc-danger); }

/* ------------------------------------------------------------- row actions */

.trc-side-actions {
  display: flex;
  flex: 0 0 auto;
  gap: 0;
}
.trc-side-actions .trc-btn {
  min-height: 26px;
  width: 26px;
  padding: 0;
  font-size: 13px;
  line-height: 1;
  color: var(--trc-text-3);
}
.trc-side-actions .trc-btn:hover { color: var(--trc-text); }
/* An action the reader switched ON (bookmarked, queued). Accent is right here:
   it marks a deliberate user choice, not a document state. */
.trc-side-actions .trc-btn.is-on { color: var(--trc-accent); }
.trc-side-actions [data-side-fav].is-on { color: var(--trc-warning); }

/* On a pointer device the actions stay out of the way until the row is under
   the cursor. On touch there is no hover, so they are always visible. */
@media (hover: hover) and (pointer: fine) {
  .trc-side-actions { opacity: 0; transition: opacity .12s ease; }
  .trc-side-item:hover .trc-side-actions,
  .trc-side-item:focus-within .trc-side-actions,
  .trc-side-actions .trc-btn.is-on { opacity: 1; }
}

/* --------------------------------------------------------- filter feedback */

.trc-side-empty {
  padding: var(--trc-s4) var(--trc-s2);
  color: var(--trc-text-3);
  font-size: 13px;
  text-align: center;
}

/* Filtering hides the current row's neighbours; keep the marker meaningful. */
.trc-reader-side.is-filtered .trc-side-item.is-current { border-left-color: var(--trc-text-2); }

/* A row action that is waiting on the network. Dimmed rather than spinning:
   the wait is usually imperceptible, and a spinner that flashes for 80 ms is
   noise. What matters is that a SLOW one no longer looks like a dead button. */
.trc-side-actions .trc-btn.is-busy {
  opacity: .45;
  cursor: progress;
}

/* --------------------------------------------------------------- the toggle */

/* A column needs no button — and neither does it need a way to close.
   sidebar.js keeps aria-expanded correct either way. */
.trc-side-toggle,
.trc-side-close { display: none; }

/* The ✕ inside the drawer's own head. The open drawer covers the ☰ that opened
   it, so without this the only exit is the backdrop — and a blank strip does
   not read as a control. It sits hard against the right edge of the head. */
.trc-side-close {
  min-height: 30px;
  width: 30px;
  padding: 0;
  font-size: 15px;
  line-height: 1;
}

/* ------------------------------------------------------------- the backdrop */

.trc-side-backdrop {
  position: fixed;
  inset: 0;
  z-index: calc(var(--trc-z-modal) - 1);
  background: var(--trc-overlay);
}
.trc-side-backdrop[hidden] { display: none; }

/* =============================== ≤860px ================================== */

/* Between 860 and 1180 the notes column would squeeze the reading measure, so
   the grid drops to index + statute and notes move below. */
@media (max-width: 1180px) {
  .trc-reader-layout .trc-reader-wrap {
    grid-template-columns: 240px minmax(0, 1fr);
  }
}

@media (max-width: 860px) {
  .trc-reader-layout .trc-reader-wrap {
    display: block;
    max-width: none;
  }

  .trc-side-toggle,
  .trc-side-close { display: inline-flex; }

  /* The head carries a control now, and a button on a text baseline sits
     slightly high. `strong` already has flex:1, so ✕ lands on the right. */
  .trc-side-head { align-items: center; }

  .trc-reader-side {
    position: fixed;
    top: var(--trc-header-total);
    left: 0;
    bottom: 0;
    z-index: var(--trc-z-modal);
    width: min(86vw, 320px);
    max-height: none;
    border-width: 0 var(--trc-border-w) 0 0;
    border-radius: 0;
    box-shadow: var(--trc-shadow-pop);
    /* Kept in the DOM (and out of the a11y tree) so the drawer can animate. */
    visibility: hidden;
    transform: translateX(-101%);
    transition: transform .18s ease, visibility 0s linear .18s;
  }

  .trc-reader-side.is-open {
    visibility: visible;
    transform: none;
    transition: transform .18s ease;
  }

  .trc-side-list { padding-bottom: calc(var(--trc-s5) + env(safe-area-inset-bottom)); }

  /* Bigger tap targets, and the actions are never hover-revealed here. */
  .trc-side-link { padding: 8px 0; font-size: 14px; }
  .trc-side-actions .trc-btn { min-height: 32px; width: 32px; font-size: 15px; }
  .trc-side-item { contain-intrinsic-size: auto 40px; }

  /* While the drawer is open the page behind it must not scroll. */
  body.trc-side-open { overflow: hidden; }
}

@media print {
  .trc-reader-side,
  .trc-side-toggle,
  .trc-side-backdrop { display: none !important; }
  .trc-reader-layout .trc-reader-wrap { display: block; }
}
