/* ==========================================================================
   layout.css — application shell, sidebar, topbar, workspace skeleton
   Desktop-first. All breakpoint transformations live in responsive.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Base / reset additions on top of Bootstrap's reboot
   -------------------------------------------------------------------------- */
html,
body {
  height: 100%;
}

.tn-body {
  margin: 0;
  background: var(--tn-app-bg);
  color: var(--tn-text);
  font-family: var(--tn-font-sans);
  font-size: var(--tn-fs-base);
  line-height: var(--tn-lh-base);
  overflow: hidden;              /* the shell scrolls internally, not the page */
  -webkit-text-size-adjust: 100%;
  text-rendering: optimizeLegibility;
}

[hidden] {
  display: none !important;
}

/* Used by jQuery instead of .show()/.hide(), which would write inline styles. */
.is-hidden {
  display: none !important;
}

.is-fading {
  opacity: 0;
  transition: opacity var(--tn-dur-fast) var(--tn-ease);
}

.sr-only {
  position: absolute !important;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  top: -60px;
  left: var(--tn-sp-5);
  z-index: var(--tn-z-toast);
  padding: var(--tn-sp-4) var(--tn-sp-6);
  background: var(--tn-accent);
  color: var(--tn-text-inverse);
  border-radius: 0 0 var(--tn-radius-md) var(--tn-radius-md);
  font-weight: var(--tn-fw-semibold);
  text-decoration: none;
  transition: top var(--tn-dur-fast) var(--tn-ease);
}

.skip-link:focus {
  top: 0;
  color: var(--tn-text-inverse);
}

:focus-visible {
  outline: var(--tn-focus-outline);
  outline-offset: 1px;
}

/* --------------------------------------------------------------------------
   Shell
   -------------------------------------------------------------------------- */
.app-shell {
  display: flex;
  height: 100vh;
  height: 100dvh;
  width: 100%;
  overflow: hidden;
}

.app-main {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
}

/* --------------------------------------------------------------------------
   Sidebar
   -------------------------------------------------------------------------- */
.sidebar {
  display: flex;
  flex: 0 0 var(--tn-w-sidebar);
  flex-direction: column;
  width: var(--tn-w-sidebar);
  min-height: 0;
  background: var(--tn-side-bg);
  border-right: 1px solid var(--tn-side-border);
  color: var(--tn-side-text);
  z-index: var(--tn-z-sidebar);
  transition: flex-basis var(--tn-dur-base) var(--tn-ease),
              width var(--tn-dur-base) var(--tn-ease);
}

.app-shell.is-collapsed .sidebar {
  flex-basis: var(--tn-w-sidebar-collapsed);
  width: var(--tn-w-sidebar-collapsed);
}

.sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--tn-sp-5);
  height: var(--tn-h-topbar);
  padding: 0 var(--tn-sp-5);
  border-bottom: 1px solid var(--tn-side-border);
  flex: 0 0 auto;
}

.sidebar__logo {
  display: grid;
  flex: 0 0 auto;
  place-items: center;
  width: 32px;
  height: 32px;
  background: var(--tn-side-logo-bg);
  border-radius: var(--tn-radius-md);
  color: var(--tn-side-text-strong);
  font-size: var(--tn-fs-sm);
  font-weight: var(--tn-fw-bold);
  letter-spacing: 0.02em;
}

.sidebar__brand-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
}

.sidebar__brand-name {
  color: var(--tn-side-text-strong);
  font-size: var(--tn-fs-lg);
  font-weight: var(--tn-fw-semibold);
  line-height: 1.15;
  white-space: nowrap;
}

.sidebar__brand-env {
  color: var(--tn-side-text-muted);
  font-size: var(--tn-fs-xs);
  white-space: nowrap;
}

.sidebar__close {
  display: none;              /* only used by the mobile drawer */
  place-items: center;
  width: 34px;
  height: 34px;
  margin-left: auto;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--tn-radius-sm);
  color: var(--tn-side-text);
  font-size: var(--tn-fs-lg);
  cursor: pointer;
}

.sidebar__close:hover {
  background: var(--tn-side-hover-bg);
  color: var(--tn-side-text-strong);
}

.sidebar__close:focus-visible {
  outline: none;
  border-color: var(--tn-side-active-bar);
}

.sidebar__search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  padding: var(--tn-sp-5) var(--tn-sp-5) var(--tn-sp-4);
}

.sidebar__search .bi {
  position: absolute;
  left: calc(var(--tn-sp-5) + var(--tn-sp-4));
  color: var(--tn-side-text-muted);
  font-size: var(--tn-fs-md);
  pointer-events: none;
}

.sidebar__search-input {
  width: 100%;
  height: 32px;
  padding: 0 var(--tn-sp-4) 0 var(--tn-sp-9);
  background: var(--tn-side-bg-raised);
  border: 1px solid var(--tn-side-border);
  border-radius: var(--tn-radius-sm);
  color: var(--tn-side-text-strong);
  font-family: inherit;
  font-size: var(--tn-fs-md);
}

.sidebar__search-input::placeholder {
  color: var(--tn-side-text-muted);
}

/* The weakest focus indicator in the prototype: a 1px border recolour and
   an explicit box-shadow:none, so a keyboard user got almost nothing. It now
   carries a ring as well — in the sidebar's own active-marker colour, because
   the application's accent ring is invisible against the blue rail.

   Kept on :focus rather than :focus-visible: this is a text input, so the
   caret is already there on click, and a second rule would only sit behind
   this one in the cascade. */
.sidebar__search-input:focus {
  outline: none;
  border-color: var(--tn-side-active-bar);
  box-shadow: 0 0 0 3px var(--tn-side-focus-ring);
}

.sidebar__nav {
  flex: 1 1 auto;
  min-height: 0;
  padding: var(--tn-sp-2) var(--tn-sp-4) var(--tn-sp-6);
  overflow-x: hidden;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: var(--tn-side-hover-bg) transparent;
}

.sidebar__nav::-webkit-scrollbar {
  width: 8px;
}

.sidebar__nav::-webkit-scrollbar-thumb {
  background: var(--tn-side-hover-bg);
  border-radius: var(--tn-radius-pill);
}

.sidebar__group-label {
  padding: var(--tn-sp-6) var(--tn-sp-4) var(--tn-sp-3);
  color: var(--tn-side-text-muted);
  font-size: var(--tn-fs-xxs);
  /* 500, not 600: these are 11px uppercase with caps tracking, which is
     already loud enough to read as a heading. Dropping the step leaves the
     rail with a clean three-level ladder — section, item, active item. */
  font-weight: var(--tn-fw-medium);
  letter-spacing: var(--tn-tracking-caps);
  text-transform: uppercase;
}

.nav-item {
  position: relative;
}

.nav-link {
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--tn-sp-5);
  width: 100%;
  min-height: 36px;
  padding: var(--tn-sp-3) var(--tn-sp-4);
  background: none;
  border: 0;
  border-radius: var(--tn-radius-sm);
  color: var(--tn-side-text);
  /* 14px: the brief target band for navigation, and with Plex ~6% wider
     than the previous face it reads at about the size the rail already had.
     Weight stays 400 here and 600 on .is-active, so the rail has exactly
     one emphasised item and the rest stays quiet. */
  font-size: var(--tn-fs-md);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--tn-dur-fast) var(--tn-ease),
              color var(--tn-dur-fast) var(--tn-ease);
}

.nav-link:hover,
.nav-link:focus-visible {
  background: var(--tn-side-hover-bg);
  color: var(--tn-side-text-strong);
}

.nav-link__icon {
  flex: 0 0 24px;
  font-size: var(--tn-fs-xl);
  line-height: 1;
  text-align: center;
}

.nav-link__text {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.nav-link__caret {
  flex: 0 0 auto;
  color: var(--tn-side-text-muted);
  font-size: var(--tn-fs-sm);
  transition: transform var(--tn-dur-fast) var(--tn-ease);
}

.nav-item.is-open > .nav-link .nav-link__caret {
  transform: rotate(90deg);
}

.nav-link__badge {
  flex: 0 0 auto;
  padding: 1px var(--tn-sp-3);
  background: var(--tn-side-hover-bg);
  border-radius: var(--tn-radius-pill);
  color: var(--tn-side-text-strong);
  font-size: var(--tn-fs-xxs);
  font-weight: var(--tn-fw-semibold);
}

.nav-item.is-active > .nav-link,
.nav-link.is-active {
  background: var(--tn-side-active-bg);
  color: var(--tn-side-text-strong);
  font-weight: var(--tn-fw-semibold);
}

.nav-item.is-active > .nav-link::before,
.nav-link.is-active::before {
  content: "";
  position: absolute;
  top: 6px;
  bottom: 6px;
  left: -4px;
  width: 3px;
  background: var(--tn-side-active-bar);
  border-radius: var(--tn-radius-pill);
}

.nav-sub {
  display: none;
  margin: var(--tn-sp-1) 0 var(--tn-sp-3);
  padding-left: calc(var(--tn-sp-4) + 24px + var(--tn-sp-5) - 12px);
  border-left: 1px solid var(--tn-side-border);
  margin-left: calc(var(--tn-sp-4) + 12px);
}

.nav-item.is-open > .nav-sub {
  display: block;
}

.nav-sub .nav-link {
  min-height: 30px;
  padding: var(--tn-sp-2) var(--tn-sp-4);
  color: var(--tn-side-text-muted);
  font-size: var(--tn-fs-md);
}

.nav-sub .nav-link:hover,
.nav-sub .nav-link:focus-visible {
  color: var(--tn-side-text-strong);
}

.nav-sub .nav-link.is-active {
  background: var(--tn-side-active-bg);
  color: var(--tn-side-text-strong);
}

.nav-sub .nav-link.is-active::before {
  left: calc(-1 * var(--tn-sp-4) - 12px - 1px);
}

.sidebar__foot {
  flex: 0 0 auto;
  padding: var(--tn-sp-4);
  border-top: 1px solid var(--tn-side-border);
}

.sidebar__collapse {
  display: flex;
  align-items: center;
  gap: var(--tn-sp-5);
  width: 100%;
  min-height: 34px;
  padding: var(--tn-sp-3) var(--tn-sp-4);
  background: none;
  border: 0;
  border-radius: var(--tn-radius-sm);
  color: var(--tn-side-text-muted);
  font-size: var(--tn-fs-md);
  cursor: pointer;
}

.sidebar__collapse .bi {
  flex: 0 0 24px;
  font-size: var(--tn-fs-lg);
  text-align: center;
  transition: transform var(--tn-dur-base) var(--tn-ease);
}

.sidebar__collapse:hover {
  background: var(--tn-side-hover-bg);
  color: var(--tn-side-text-strong);
}

/* ---- collapsed (icon rail) state ---- */
.app-shell.is-collapsed .sidebar__brand-text,
.app-shell.is-collapsed .sidebar__search,
.app-shell.is-collapsed .sidebar__group-label,
.app-shell.is-collapsed .nav-link__text,
.app-shell.is-collapsed .nav-link__caret,
.app-shell.is-collapsed .nav-link__badge,
.app-shell.is-collapsed .nav-sub,
.app-shell.is-collapsed .sidebar__collapse-text {
  display: none;
}

.app-shell.is-collapsed .sidebar__brand {
  justify-content: center;
  padding: 0;
}

.app-shell.is-collapsed .nav-link {
  justify-content: center;
  padding: var(--tn-sp-3) 0;
  min-height: 40px;
}

.app-shell.is-collapsed .sidebar__collapse {
  justify-content: center;
}

.app-shell.is-collapsed .sidebar__collapse .bi {
  transform: rotate(180deg);
}

/* Icon-rail tooltip — hover convenience only; never the sole affordance
   (every rail icon still has an accessible name via aria-label). */
.app-shell.is-collapsed .nav-link[data-label]:hover::after,
.app-shell.is-collapsed .nav-link[data-label]:focus-visible::after {
  content: attr(data-label);
  position: absolute;
  left: calc(100% + var(--tn-sp-3));
  top: 50%;
  transform: translateY(-50%);
  z-index: var(--tn-z-menu);
  padding: var(--tn-sp-2) var(--tn-sp-5);
  background: var(--tn-side-bg-raised);
  border: 1px solid var(--tn-side-border);
  border-radius: var(--tn-radius-sm);
  box-shadow: var(--tn-shadow-md);
  color: var(--tn-side-text-strong);
  font-size: var(--tn-fs-md);
  white-space: nowrap;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   Scrim shared by the mobile nav drawer
   -------------------------------------------------------------------------- */
.scrim {
  position: fixed;
  inset: 0;
  z-index: var(--tn-z-scrim);
  background: var(--tn-scrim);
}

/* --------------------------------------------------------------------------
   Topbar
   -------------------------------------------------------------------------- */
.topbar {
  display: flex;
  align-items: center;
  gap: var(--tn-sp-5);
  flex: 0 0 auto;
  height: var(--tn-h-topbar);
  padding: 0 var(--tn-pad-inline);
  background: var(--tn-topbar-bg);
  border-bottom: 1px solid var(--tn-topbar-border);
  box-shadow: var(--tn-shadow-xs);
  z-index: var(--tn-z-topbar);
}

/* NOTE ON SPECIFICITY
   components.css loads after layout.css, so a bare `.topbar__nav-toggle`
   rule would lose to `.icon-btn { display: inline-grid }`. Every
   show/hide rule for an element that also carries a component class is
   therefore scoped to its parent (0,2,0) — in this file and in
   responsive.css alike. */
.topbar .topbar__nav-toggle {
  display: none;
}

.topbar .topbar__title {
  display: none;
  font-size: var(--tn-fs-lg);
  font-weight: var(--tn-fw-semibold);
}

/* Branding holds the left of the bar: the product mark, a hairline, then the
   customer mark. Both are background images swapped per theme through a token,
   because a CSS-masked SVG paints nothing over file:// and this prototype has
   to run by double-clicking a page. */
.topbar__brand {
  display: inline-flex;
  align-items: center;
  gap: var(--tn-sp-5);
  flex: 0 0 auto;
}

.topbar__logo {
  display: block;
  flex: 0 0 auto;
  background-position: left center;
  background-repeat: no-repeat;
  background-size: contain;
}

.topbar__logo--tournate {
  width: var(--tn-w-logo-tournate);
  height: var(--tn-h-logo-tournate);
  background-image: var(--tn-logo-tournate);
}

.topbar__logo--customer {
  width: var(--tn-w-logo-customer);
  height: var(--tn-h-logo-customer);
  background-image: url("../assets/customer-logo.png");
  filter: var(--tn-logo-customer-filter);
}

.topbar__brand-divider {
  flex: 0 0 auto;
  width: 1px;
  height: 22px;
  background: var(--tn-topbar-brand-divider);
}

/* Topbar order (desktop):  Brand │ Market │ Search │ … │ Dark · actions
   The Market select sits alone in .topbar__context so js/responsive.js can
   relocate it into the context strip below 992px. */
.topbar__search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 300px;
  max-width: 520px;
  min-width: 0;
}

.topbar__search-icon {
  position: absolute;
  top: 50%;
  left: var(--tn-sp-5);
  transform: translateY(-50%);
  color: var(--tn-text-secondary);
  font-size: var(--tn-fs-base);
  pointer-events: none;
}

.topbar__search-input {
  flex: 1 1 auto;
  width: 100%;
  min-width: 0;
  height: var(--tn-h-context);
  padding: 0 72px 0 var(--tn-sp-10);
  background: var(--tn-surface-sunken);
  border: 1px solid var(--tn-input-border);
  border-radius: var(--tn-radius-md);
  color: var(--tn-text);
  font-family: inherit;
  font-size: var(--tn-fs-base);
}

.topbar__search-input::placeholder {
  color: var(--tn-text-muted);
}

.topbar__search-input:focus {
  background: var(--tn-surface);
  border-color: var(--tn-accent);
  box-shadow: var(--tn-focus-ring);
  outline: none;
}

.topbar__kbd {
  position: absolute;
  top: 50%;
  right: var(--tn-sp-4);
  transform: translateY(-50%);
  padding: 1px var(--tn-sp-3);
  background: var(--tn-surface);
  border: 1px solid var(--tn-border-strong);
  border-radius: var(--tn-radius-xs);
  color: var(--tn-text-secondary);
  font-family: var(--tn-font-sans);
  font-size: var(--tn-fs-chrome-label);
  pointer-events: none;
}

.topbar__search .topbar__search-close {
  display: none;
  position: absolute;
  top: 50%;
  right: var(--tn-sp-2);
  transform: translateY(-50%);
}

.topbar__context {
  display: flex;
  align-items: center;
  gap: var(--tn-sp-3);
  flex: 0 0 auto;
}

.topbar__actions {
  display: flex;
  align-items: center;
  gap: var(--tn-sp-2);
  margin-left: auto;
  flex: 0 0 auto;
}

.topbar .topbar__search-open {
  display: none;
}

/* --------------------------------------------------------------------------
   Context strip (surfaces the operating context when the topbar sheds it)
   -------------------------------------------------------------------------- */
.context-strip {
  display: none;
  align-items: center;
  gap: var(--tn-sp-4);
  flex: 0 0 auto;
  height: 34px;
  padding: 0 var(--tn-pad-inline);
  background: var(--tn-surface-raised);
  border-bottom: 1px solid var(--tn-border);
  overflow-x: auto;
  scrollbar-width: none;
}

.context-strip::-webkit-scrollbar {
  display: none;
}

/* --------------------------------------------------------------------------
   Workspace
   -------------------------------------------------------------------------- */
.workspace {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  min-width: 0;
  overflow: hidden;
}

.page-header {
  display: flex;
  align-items: flex-start;
  gap: var(--tn-sp-6);
  flex: 0 0 auto;
  padding: var(--tn-sp-5) var(--tn-pad-inline) var(--tn-sp-5);
  background: var(--tn-surface);
  border-bottom: 1px solid var(--tn-border);
}

.page-header__left {
  min-width: 0;
  flex: 1 1 auto;
}

.page-header__right {
  display: flex;
  align-items: center;
  gap: var(--tn-sp-4);
  flex: 0 0 auto;
}

/* The title is the anchor of the page: bold and optically tightened so it
   carries without being enlarged. */
.page-header__title {
  margin: var(--tn-sp-1) 0 var(--tn-sp-2);
  color: var(--tn-text);
  font-size: var(--tn-fs-title);
  /* 600. The size (23px) already separates this from everything else on
     the page, so the extra weight step was redundant under Plex. */
  font-weight: var(--tn-fw-semibold);
  letter-spacing: -0.015em;
  line-height: var(--tn-lh-tight);
}

/* Metadata sits a step below the title: smaller and quieter, with only the
   values themselves kept strong. */
.page-header__meta {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--tn-sp-3) var(--tn-sp-4);
  color: var(--tn-text-secondary);
  font-size: var(--tn-fs-sm);
}

.meta-item {
  display: inline-flex;
  align-items: center;
  gap: var(--tn-sp-3);
  white-space: nowrap;
}

.meta-item strong {
  color: var(--tn-text);
  font-weight: var(--tn-fw-bold);
}

.meta-item--muted {
  color: var(--tn-text-muted);
}

.meta-sep {
  width: 1px;
  height: 11px;
  background: var(--tn-border-strong);
}

/* --------------------------------------------------------------------------
   Workspace body — the master/detail region
   -------------------------------------------------------------------------- */
.workspace-body {
  position: relative;
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  padding: var(--tn-pad-workspace);
  overflow: hidden;
}

.tab-panel {
  display: none;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--tn-gap-panel);
  min-height: 0;
}

.tab-panel.is-active {
  display: flex;
}

/* --------------------------------------------------------------------------
   THE DOCUMENT WORKSPACE

   Every screen built before Import and Loading States divides a FIXED
   viewport into panes: .workspace, .workspace-body and .tab-panel are all
   `flex: 1 1 auto; overflow: hidden`, panels share out the height that
   exists, and anything too long scrolls INSIDE its own panel — a
   .grid-wrap, a .panel__body.

   A reference page is not that shape. It is a column of panels that is
   simply taller than the screen, and in the paned model it has nowhere to
   go: the panels are squeezed towards zero and then clipped. Worse, the
   clipping is VERTICAL, and the horizontal-overflow gate in
   tools/run-tests.mjs cannot see it — which is exactly how ten panels
   showing nothing but their own headers passed every check.

   So a page declares which it is. `--doc` means "this is a document: let
   it be as tall as it is, and scroll the workspace". Nothing about the
   paned screens changes, because nothing about the base rules changed.
   -------------------------------------------------------------------------- */
.workspace-body--doc {
  overflow-y: auto;
  overflow-x: hidden;
}

/* The panels stack and take the height their content needs, rather than
   competing for a height that was never going to be enough. */
.workspace-body--doc > .tab-panel.is-active {
  display: block;
  flex: 0 0 auto;
  min-height: 0;
}

.workspace-body--doc .panel {
  flex: 0 0 auto;
  min-height: 0;
  margin-bottom: var(--tn-gap-panel);
}

.workspace-body--doc .panel:last-child { margin-bottom: 0; }

/* A grid inside a document page is bounded so one long table cannot make
   the whole page thousands of pixels tall; it scrolls in place, the same
   way it does on a paned screen. */
.workspace-body--doc .grid-wrap--scroll {
  max-height: 60vh;
}

.panel--master {
  flex: var(--tn-split-master) 1 0;
  min-height: 140px;
}
/* ==========================================================================
   RESIZABLE PANEL PAIRS

   A .split-pair is two panels with a draggable boundary between them. One
   custom property does all the work:

     --tn-split   the boundary's position as a percentage of the row

   It sets the FIRST child's width and the splitter's left offset at once, so
   the handle cannot drift away from the edge it moves. The second child takes
   whatever is left, which is what keeps the row's total width constant: one
   side grows by exactly what the other gives up.

   Half the gap is subtracted from the first child so the boundary sits in the
   MIDDLE of the gap rather than against one panel's edge.

   Behaviour lives in js/panel-resize.js, which also injects the splitter —
   pages only declare which two panels form a pair.
   ========================================================================== */
.split-pair {
  position: relative;
}

/* The two sides are marked by js/panel-resize.js rather than picked by
   position: on the left/right layout the second CHILD is the hidden
   .detail-tabs strip, and the real second side is the .detail-stack after
   it. Explicit marks make the pair independent of that chrome. */
.split-pair > [data-split-side="a"] {
  flex: 0 0 calc(var(--tn-split, 50%) - var(--tn-gap-panel) / 2);
  min-width: 0;
}

.split-pair > [data-split-side="b"] {
  flex: 1 1 0;
  min-width: 0;
}

/* The hit target is 11px; the line inside it is 1px. The strip is centred on
   the boundary and sits over the gap, so it costs the layout nothing. */
/* Bootstrap's reboot styles the splitter twice over — button:not(:disabled)
   AND [type="button"]:not(:disabled), the second at (0,2,0) — so the resize
   cursor needs to outrank that, not merely follow it in source order. The
   cursor IS the affordance here, so it has to win. */
.split-pair > button.panel-splitter {
  cursor: col-resize;
}

.panel-splitter {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--tn-split, 50%);
  z-index: 2;
  width: 11px;
  margin: 0 0 0 -6px;
  padding: 0;
  background: none;
  border: 0;
  cursor: col-resize;
  touch-action: none;
}

/* Invisible at rest: the two panel borders already mark the boundary, and a
   third permanent line there would be one line too many. The cursor is the
   affordance; hover and focus bring the rule up. */
.panel-splitter::after {
  content: "";
  position: absolute;
  top: var(--tn-sp-2);
  bottom: var(--tn-sp-2);
  left: 50%;
  width: 2px;
  margin-left: -1px;
  border-radius: var(--tn-radius-pill);
  background: var(--tn-border-strong);
  opacity: 0;
  transition: opacity var(--tn-dur-fast) var(--tn-ease),
              background var(--tn-dur-fast) var(--tn-ease);
}

.panel-splitter:hover::after {
  opacity: 1;
}

.panel-splitter:focus-visible {
  outline: none;
}

.panel-splitter:focus-visible::after {
  opacity: 1;
  background: var(--tn-accent);
}

.split-pair.is-splitting .panel-splitter::after {
  opacity: 1;
  background: var(--tn-accent);
}

/* During a drag the cursor must not flicker as the pointer crosses panels,
   and nothing may be selected by accident. */
body.is-panel-resizing {
  user-select: none;
}

body.is-panel-resizing,
body.is-panel-resizing * {
  cursor: col-resize !important;
}


.split-row {
  display: flex;
  gap: var(--tn-gap-panel);
  flex: var(--tn-split-detail) 1 0;
  min-height: 160px;
}

.split-row > .panel--detail {
  flex: var(--tn-split-left) 1 0;
  min-width: 0;
}

.split-row > .panel--prices {
  flex: var(--tn-split-right) 1 0;
  min-width: 0;
}

/* Detail pane tabs — only rendered below the split breakpoint */
.detail-tabs {
  display: none;
}

/* Maximise / restore */
.workspace-body.has-maximised .panel:not(.is-maximised),
.workspace-body.has-maximised .detail-tabs {
  display: none;
}

.workspace-body.has-maximised .split-row {
  flex: 1 1 auto;
}

.panel.is-maximised {
  flex: 1 1 auto !important;
}

/* --------------------------------------------------------------------------
   Mobile drill-down scaffolding (activated in responsive.css)
   -------------------------------------------------------------------------- */
.drill-bar,
.mobile-panes {
  display: none;
}
