/* Flow-graph page layout (P3-008; full-bleed + mobile in P3.1-008).
 *
 * #graph MUST have real dimensions BEFORE cytoscape initializes: it
 * measures the container at init and a plain empty div has
 * clientHeight 0, so the canvas renders blank (codex P3-008 P1) -- every
 * sizing rule below therefore resolves to a concrete height, including
 * inside the mobile breakpoint.
 * External first-party file (never inline) so P3-014's strict CSP
 * needs no style-src 'unsafe-inline'.
 */

#graph-shell {
  display: flex;
  gap: 1rem;
  align-items: stretch;
  /* Never let the split row push the page wider than its container: the rail is
     fixed-width and the stage shrinks (min-width:0 below), so the two always fit
     side by side instead of widening to add the panel (P3.3-011 #1). */
  max-width: 100%;
}

/* P3.3-010 #4: the control fieldsets (Layout / Stage filter) now live inside
   console-card sub-panels in the right rail — strip the default fieldset
   chrome so the card surface is the only frame. */
#console-rail fieldset {
  margin: 0;
  padding: 0;
  border: 0;
}

/* P3.3 #1: the Layout selector is a compact segmented control — a flex ROW of
   muted buttons (side-by-side, smaller font than the 0.95rem base button), the
   active layout RAISED via aria-pressed. Mirrors the #graph-tools / .view-
   switcher token usage so the three control surfaces read consistently. */
/* P3.3-016 #4: the two-axis layout control — #layout-toggle (Arrangement) +
   #density-toggle (Density) — share the compact segmented look: a flex ROW of
   muted buttons (smaller font than the 0.95rem base button), the active option
   RAISED via aria-pressed. Mirrors the #graph-tools / .view-switcher tokens so
   the control surfaces read consistently. */
#layout-toggle,
#density-toggle {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* Density toggle sits below the arrangement row in the same card; a small top
   margin separates the two axes. */
#density-toggle {
  margin-top: var(--space-2);
}

#layout-toggle button,
#density-toggle button {
  margin: 0;
  padding: 0.2rem 0.6rem;
  background: var(--btn-muted-bg);
  color: var(--btn-muted-text);
  border: 1px solid var(--btn-muted-border);
  border-radius: var(--radius-sm);
  font-size: 0.8rem;
  line-height: 1.2;
  cursor: pointer;
}

#layout-toggle button:hover,
#density-toggle button:hover {
  background: var(--btn-muted-hover-bg);
}

#layout-toggle button[aria-pressed="true"],
#density-toggle button[aria-pressed="true"] {
  background: var(--btn-bg);
  color: var(--btn-text);
  border-color: var(--btn-border);
  font-weight: 600;
}

/* P3.3-016 #4: the L→R / R→L direction toggle sits next to the arrangement
   buttons in #layout-toggle (it is a flex child); a thin left margin sets it
   apart from the arrangement segment. */
#layout-toggle .direction-toggle {
  display: inline-flex;
  gap: var(--space-2);
  margin-left: var(--space-2);
}

/* P3.3-016 #1: the six filters live in ONE "필터 · Filter" card as grouped
   sub-sections. Each <fieldset> is a compact group with a VISIBLE <legend>
   sub-section label (.filter-legend) and a thin separator above it; the controls
   inside stay small to fit the 360px rail. */
#filter-card .filter-group {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border);
}

/* The first sub-section has no separator above it (the card header already
   frames it). */
#filter-card .filter-group:first-of-type {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
}

/* The visible sub-section label: a small, bold, muted heading. Reused by the
   layout card's Arrangement/Density legends too. */
.filter-legend,
#filter-card .filter-legend {
  padding: 0;
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

/* The native/no-FX caption + min/max-input hints stay small and muted. */
.filter-note {
  margin: 0.35rem 0 0;
  font-size: 0.72rem;
  color: var(--muted);
}

/* The amount-filter per-asset <select> + the time-filter min/max field rows
   wrap compactly inside the 360px rail. */
#filter-card select,
#filter-card .filter-field {
  font-size: 0.78rem;
}

#filter-card .filter-field {
  display: inline-flex;
  flex-direction: column;
  margin-right: 0.4em;
}

#filter-card .filter-field-label {
  font-size: 0.68rem;
  color: var(--muted);
}

/* P3.3-020 #0: the native datetime-local time-filter inputs are NOT covered by
   the enumerated text-control rule in base.css (a bare `input` selector there
   would inflate the graph stage-filter checkboxes — codex P2), so without this
   they render in the browser's default datetime font and, at the inline 8.5em
   width set by makeBoundInput, clip the Korean 오전/오후 (AM/PM) marker. Scope the
   harmonising rule to #filter-card so only the time inputs pick it up: match the
   adjacent .filter-field/select font (0.78rem) + the shared surface tokens, and
   FLOOR the width with min-width (an inline `width` cannot be overridden by a CSS
   `width`, but a larger `min-width` still wins) so 오전/오후 always fits. The popup
   calendar is browser-owned and stays the UA default. */
/* P3.3-021 #3: WinUI (Windows date/time picker) styling cues — a clearly
   bordered field that lifts to the raised surface on hover, an accent focus
   RING (not just a border tint), and the active segment highlighted in the
   accent the way WinUI's CalendarDatePicker/TimePicker highlight the field
   under edit. CSS-only (Q2) — the popup calendar stays UA-owned. */
#filter-card input[type="datetime-local"] {
  font-family: inherit;
  font-size: 0.78rem;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2);
  min-width: 14.5em;
  max-width: 100%;
  transition:
    border-color 0.12s ease,
    background-color 0.12s ease,
    box-shadow 0.12s ease;
}

#filter-card input[type="datetime-local"]:hover {
  background: var(--surface-raised);
  border-color: var(--accent);
}

/* WinUI focus cue: the accent border + a soft accent ring (focus-visible
   semantics via :focus, no JS). */
#filter-card input[type="datetime-local"]:focus {
  outline: none;
  background: var(--surface-raised);
  border-color: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
}

/* The calendar picker glyph is dark by default — lighten it on the dark theme so
   it reads on the dark field, and reset to the UA default on the light theme. */
#filter-card input[type="datetime-local"]::-webkit-calendar-picker-indicator {
  cursor: pointer;
  border-radius: var(--radius-sm);
  filter: invert(0.85) brightness(1.1);
}

:root[data-theme="light"]
  #filter-card
  input[type="datetime-local"]::-webkit-calendar-picker-indicator {
  filter: none;
}

/* Tidy the segmented date/time edit fields (Chromium/WebKit; Firefox degrades
   gracefully — the property is simply ignored there). */
#filter-card input[type="datetime-local"]::-webkit-datetime-edit {
  padding: 1px 0;
}

/* WinUI active-segment highlight: the hour / minute / AM-PM (오전·오후) field
   being edited fills with the accent, exactly like the highlighted column of a
   WinUI TimePicker. Scoped to #filter-card so only the filter time inputs get
   it (a bare ::-webkit-datetime-edit-*-field rule would touch every datetime
   input on the page). */
#filter-card input[type="datetime-local"]::-webkit-datetime-edit-hour-field:focus,
#filter-card input[type="datetime-local"]::-webkit-datetime-edit-minute-field:focus,
#filter-card input[type="datetime-local"]::-webkit-datetime-edit-day-field:focus,
#filter-card input[type="datetime-local"]::-webkit-datetime-edit-month-field:focus,
#filter-card input[type="datetime-local"]::-webkit-datetime-edit-year-field:focus,
#filter-card
  input[type="datetime-local"]::-webkit-datetime-edit-ampm-field:focus {
  background: var(--accent);
  color: #fff;
  border-radius: 3px;
  outline: none;
}

/* Visually-hidden but screen-reader-available label (the panel-header carries
   the visible title, so the fieldset <legend> would duplicate it). */
.vca-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Legend (P3.1-009c): a control-band fieldset joining the graph-controls
   flex naturally. Shape glyphs are static; stage swatches filled by JS. */
#graph-legend #legend-shapes {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem 1.25rem;
  margin: 0.25rem 0 0.5rem;
  padding-left: 0;
  list-style: none;
  font-size: 0.85rem;
}

#graph-legend .legend-glyph {
  display: inline-block;
  width: 1.2em;
  text-align: center;
  margin-right: 0.3em;
}

#legend-stages,
#legend-chains,
#legend-services {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 0.75rem;
  font-size: 0.85rem;
}

#legend-stages .legend-stage,
#legend-chains .legend-stage,
#legend-services .legend-stage {
  display: inline-flex;
  align-items: center;
}

/* P3.3-017b: the per-service legend groups concrete service chips under a
   category header. Each group is a full-width row (categories stack); the
   header is a small bold muted label, the chips wrap beside it. */
#legend-services .legend-service-group {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem 0.6rem;
  flex-basis: 100%;
}

#legend-services .legend-service-header {
  font-size: 0.72rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

/* P3.3-017b: the per-service FILTER groups its checkboxes under a category
   header row (a small bold muted label on its own line). */
#service-filter .filter-group-header {
  display: block;
  margin-top: 0.35rem;
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

#service-filter .filter-group-header:first-of-type {
  margin-top: 0;
}

/* P3.3-017c #3: the per-group "전체선택 · All" / "해제 · None" controls. Compact
   token buttons (the muted segmented look shared with #graph-tools / the layout
   toggle) on their own line below each checkbox group, so they read on the light
   console surface and stay subtle. They consume the shared --btn-muted-* tokens
   — never a hard-coded palette. */
.filter-select-all {
  display: flex;
  gap: var(--space-2);
  margin-top: 0.35rem;
}

.filter-select-all button {
  margin: 0;
  padding: 0.1rem 0.5rem;
  background: var(--btn-muted-bg);
  color: var(--btn-muted-text);
  border: 1px solid var(--btn-muted-border);
  border-radius: var(--radius-sm);
  font-size: 0.72rem;
  line-height: 1.2;
  cursor: pointer;
}

.filter-select-all button:hover {
  background: var(--btn-muted-hover-bg);
}

/* P3.3-017d #2: the "필터 결과만 보기 · Focus on filtered" toggle (a checkbox +
   label) sits in the Layout card under the arrangement/density controls. Compact
   inline label, consistent with the surrounding control surface. */
#focus-toggle .focus-toggle-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.8rem;
  cursor: pointer;
}

#legend-stages .legend-swatch,
#legend-chains .legend-swatch {
  display: inline-block;
  width: 0.8em;
  height: 0.8em;
  margin-right: 0.3em;
}

/* The stage wraps the cytoscape canvas + the in-canvas tools overlay and
   carries the concrete working-area height (codex P3-008 P1: #graph must
   have real dimensions before cytoscape init — it now fills the stage).
   position:relative anchors the absolutely-positioned #graph-tools. */
#graph-stage {
  position: relative;
  flex: 1 1 auto;
  /* Allow the stage to shrink below the canvas's intrinsic width when the
     console rail returns (Graph->Split): a flex item defaults to
     min-width:auto and would otherwise refuse to shrink, widening the row to
     fit both the full-size graph and the panel (P3.3-011 #1). */
  min-width: 0;
  /* Full-viewport working area: viewport minus the header/tabs band (~230px
     on desktop now the controls moved into the right rail, P3.3-010 #4),
     floored so small windows stay usable. */
  height: calc(100vh - 230px);
  min-height: 480px;
}

#graph {
  width: 100%;
  height: 100%;
  border: 1px solid #d5d8dc;
  /* Clip the cytoscape canvas to the container so a transient oversize
     (between a Graph->Split layout toggle and the next-frame cy.resize)
     can never spill past the shrunken stage (P3.3-011 #1). */
  overflow: hidden;
}

/* In-canvas control overlay: zoom +/-, the Fit/Fill view toggle and the
   open-in-new-window button. Anchored to the top-right of the stage, above
   the cytoscape canvas (z-index). Kept compact so it covers only a corner
   and the rest of the canvas stays interactive. */
/* The overlay panel uses the theme surface so the muted tool buttons read
   on it in BOTH themes (P3.3-009 #1): a translucent dark chrome made the
   white-on-light light-theme buttons clash. --surface-raised + the hairline
   border keep it legible over the canvas. */
#graph-tools {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  z-index: 5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.25rem;
  padding: 0.25rem 0.35rem;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: var(--shadow-card);
}

/* In-canvas tools are NEUTRAL buttons — they read the muted button tokens
   (defined per theme in tokens.css) rather than the primary blue fill, so
   the compact overlay stays subtle and legible on either theme. */
#graph-tools button {
  margin-top: 0;
  padding: 0.2rem 0.5rem;
  background: var(--btn-muted-bg);
  color: var(--btn-muted-text);
  border: 1px solid var(--btn-muted-border);
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  cursor: pointer;
  line-height: 1.1;
}

#graph-tools button:hover {
  background: var(--btn-muted-hover-bg);
  border-color: var(--btn-muted-border);
}

#graph-tools .graph-tools-sep {
  align-self: stretch;
  width: 1px;
  margin: 0 0.15rem;
  background: var(--border);
}

/* P3.3-008 MiroFish split console + P3.3-010 #4 controls column: the right
   rail holds the Layout / Stage filter / Legend / explainer control cards,
   then the Stage step cards, the edge inspect panel and the trace-log
   terminal. It scrolls independently alongside the fixed-height graph stage. */
#console-rail {
  flex: 0 0 360px;
  max-width: 360px;
  max-height: calc(100vh - 230px);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Keep each rail card at its natural height so the rail SCROLLS rather than
   flex-shrinking the cards (an un-pinned shrink collapsed the trace log to a
   single line). */
#console-rail > * {
  flex-shrink: 0;
}

/* "Graph" view (the header view-switcher) hides the rail so the canvas goes
   full-width; graph_page.js calls cy.resize() + fitToPanel after toggling. */
#graph-shell.graph-only #console-rail {
  display: none;
}

#detail-panel {
  min-height: 5rem;
}

/* Fund-flow explainer (P3.1-009d): the how-to-read guidance. P3.3-010 #4
   moves it into the right rail as a console-card sub-panel (collapsed by
   default so the rail stays compact); .vca-lang-hidden toggles the inactive
   language. The console-card already supplies the surface + border. */
#graph-explainer .explainer-details > summary {
  cursor: pointer;
  font-weight: 600;
  list-style-position: inside;
}

#graph-explainer h3 {
  margin: 0.75rem 0 0.25rem;
  font-size: 0.9rem;
}

#graph-explainer ol {
  padding-left: 1.25rem;
  font-size: 0.85rem;
}

#graph-explainer p {
  font-size: 0.85rem;
}

#graph-explainer #lang-toggle {
  float: right;
}

.vca-lang-hidden {
  display: none;
}

/* P3.3-010 #5: floating node-detail popover anchored within #graph-stage
   (a sibling of #graph, like #graph-tools). JS sets left/top from the node's
   rendered position (clamped within the stage). Reads the console card tokens
   so it is legible on either theme; capped + scrollable so a long node detail
   never overflows the stage. */
#graph-popover {
  position: absolute;
  z-index: 6;
  width: 16rem;
  max-width: calc(100% - 1.5rem);
  max-height: calc(100% - 1.5rem);
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  font-size: 0.85rem;
}

#graph-popover[hidden] {
  display: none;
}

#graph-popover .graph-popover__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--border);
}

#graph-popover .graph-popover__title {
  font-weight: 600;
  font-size: 0.82rem;
  color: var(--heading);
}

#graph-popover .graph-popover__close {
  margin: 0;
  padding: 0 0.35rem;
  background: var(--btn-muted-bg);
  color: var(--btn-muted-text);
  border: 1px solid var(--btn-muted-border);
  border-radius: var(--radius-sm);
  font-size: 1rem;
  line-height: 1.2;
  cursor: pointer;
}

#graph-popover .graph-popover__close:hover {
  background: var(--btn-muted-hover-bg);
}

#graph-popover .graph-popover__body {
  padding: var(--space-2) var(--space-3);
  word-break: break-all;
}

#graph-popover .graph-popover__body h4 {
  margin: 0 0 var(--space-2);
  font-size: 0.85rem;
}

/* P3.3-011 #2: node-detail fields rendered as labelled chips/badges instead
   of a plain dt/dd list. Each row is a small-caps key + a pill value; the
   address / first-seen-TX chips are monospace and wrap. The node fragment
   renders into the popover body (and, on a stripped template, the fallback
   #detail-panel), so scope it to both. Reads the theme tokens — legible on
   either theme, never hardcoded hex. */
.node-detail {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.node-detail__row {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
}

.node-detail__row dt {
  flex: 0 0 5.25rem;
  margin: 0;
  color: var(--muted);
  font-size: 0.66rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.node-detail__row dd {
  margin: 0;
  min-width: 0;
}

.node-badge {
  display: inline-block;
  padding: 0.1rem var(--space-2);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 999px;
  font-size: 0.76rem;
  font-weight: 600;
  color: var(--text);
}

.node-badge--mono {
  font-family: var(--font-mono);
  font-weight: 500;
  word-break: break-all;
  /* a long mono hash reads better as a squared tag than a rounded pill */
  border-radius: var(--radius-sm);
}

.node-badge--muted {
  color: var(--muted);
  font-weight: 400;
}

/* Terminal flag: a genuine end-of-trace node is highlighted (frontier-amber
   tokens), a pass-through is muted — reusing the status-badge palette SSOT. */
.node-badge--terminal {
  color: var(--status-frontier);
  background: var(--status-frontier-bg);
  border-color: transparent;
}

/* Mobile: stack the panel under the canvas; the graph keeps a concrete
   viewport-relative height (the codex P3-008 P1 invariant). */
@media (max-width: 800px) {
  #graph-shell {
    flex-direction: column;
  }

  #graph-stage {
    height: 60vh;
    min-height: 320px;
  }

  /* Stack the rail under the canvas at full width; the graph keeps its
     concrete viewport-relative height (codex P3-008 P1 invariant). */
  #console-rail {
    flex: none;
    max-width: none;
    max-height: none;
  }
}

/* --- WinUI-style date/time picker (P3.3-023) ----------------------------- */
/* graph_time_picker.js hides the native datetime-local input (kept as the value
   sink + SR-labelled field) and shows a themed trigger that opens a flyout of
   scrollable 년/월/일/시/분/오전·오후 columns with an accent selection + ✓/✗.
   Token-only, both themes; the native popup stays UA-owned (it is unreachable
   because the input is visually hidden). */

/* visually hide the native input but keep it focusable / announced. */
.gtp-native {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* the themed trigger button (the WinUI "resting" box). */
.gtp-trigger {
  font-family: inherit;
  font-size: 0.78rem;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2);
  min-width: 14.5em;
  max-width: 100%;
  text-align: left;
  cursor: pointer;
  transition:
    border-color 0.12s ease,
    background-color 0.12s ease,
    box-shadow 0.12s ease;
}
.gtp-trigger:hover {
  background: var(--surface-raised);
  border-color: var(--accent);
}
.gtp-trigger:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
}

/* the overlay flyout (position:fixed; placed on document.body). */
.gtp-flyout {
  position: fixed;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--space-3);
  /* wide enough for the calendar + 시/분/오전·오후 columns to sit in one row
     (the .gtp-datetime nowrap layout); position() clamps the offset into the
     viewport separately, and 96vw keeps it on-screen on a narrow window. */
  max-width: min(96vw, 46em);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card, 0 8px 28px rgba(0, 0, 0, 0.35));
}
.gtp-flyout[hidden] {
  display: none;
}

.gtp-header {
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--heading);
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.gtp-cols {
  display: flex;
  gap: var(--space-2);
}

/* date (calendar) and time (시/분/오전·오후 columns) sit side by side in one row
   (나란히, user request); align their tops since the calendar is the taller box. */
.gtp-datetime {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--space-3);
  align-items: flex-start;
}
/* on a genuinely narrow window the nowrap row would overflow the 96vw flyout and
   push the time columns off-screen (codex P2), so let them wrap under the
   calendar there; a normal desktop window keeps the row 나란히 side by side. */
@media (max-width: 36em) {
  .gtp-datetime {
    flex-wrap: wrap;
  }
}

/* WinUI calendar — month grid + year-view zoom (P3.3-025). */
.gtp-calendar {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 15.5em;
}
.gtp-cal-head {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}
.gtp-cal-nav {
  font-family: inherit;
  font-size: 0.95rem;
  line-height: 1;
  width: 1.8em;
  height: 1.8em;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
}
/* the month arrows are hidden in year-view mode; the override is needed because
   .gtp-cal-nav sets display:flex, which beats the UA [hidden] { display:none }. */
.gtp-cal-nav[hidden] {
  display: none;
}
.gtp-cal-nav:hover {
  border-color: var(--accent);
}
.gtp-cal-title {
  flex: 1 1 auto;
  font-family: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  padding: var(--space-1);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--heading);
  cursor: pointer;
}
.gtp-cal-title:hover {
  background: var(--surface);
  border-color: var(--border);
}
.gtp-cal-nav:focus-visible,
.gtp-cal-title:focus-visible,
.gtp-day:focus-visible,
.gtp-year:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
}
.gtp-cal-week,
.gtp-cal-row {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.gtp-cal-wd {
  text-align: center;
  font-size: 0.68rem;
  color: var(--muted);
  padding: 0.15em 0;
}
.gtp-cal-grid {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.gtp-day,
.gtp-cal-blank {
  height: 2em;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
  border-radius: var(--radius-sm);
}
.gtp-day {
  color: var(--text);
  cursor: pointer;
  border: 1px solid transparent;
}
.gtp-day:hover {
  background: var(--surface);
}
.gtp-day.is-selected {
  background: var(--accent);
  color: #fff;
  font-weight: 600;
}
.gtp-cal-years {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-1);
}
.gtp-year {
  font-family: inherit;
  font-size: 0.8rem;
  padding: 0.5em 0;
  text-align: center;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
}
.gtp-year:hover {
  /* WinUI hover preview: accent fill + white text (white alone would be
     invisible on the light-theme --bg; the accent fill keeps it readable).
     The selected year stays distinguishable via its bold weight. */
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.gtp-year.is-selected {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
  font-weight: 600;
}

.gtp-col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.2rem;
}

.gtp-col-label {
  font-size: 0.7rem;
  color: var(--muted);
}

.gtp-list {
  /* position:relative makes THIS list the options' offsetParent, so the JS
     scrollToCenter (which reads opt.offsetTop) measures relative to the list,
     not the position:fixed flyout — without it the clicked option does not land
     in the centre. The translucent top/bottom mask fade is removed (user req). */
  position: relative;
  height: 10em;
  overflow-y: auto;
  scroll-behavior: smooth;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--bg);
}
/* half-viewport spacers above the first and below the last option so ANY clicked
   option — including the first/last and the 2-option 오전·오후 column — can scroll
   to the vertical centre (scrollToCenter clamps at the edges without them). */
.gtp-list::before,
.gtp-list::after {
  content: "";
  display: block;
  height: calc((10em - 2em) / 2);
}
.gtp-list:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 35%, transparent);
}

.gtp-opt {
  height: 2em;
  line-height: 2em;
  padding: 0 0.8em;
  text-align: center;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
}
.gtp-opt:hover {
  background: var(--surface);
}
.gtp-opt.is-selected {
  background: var(--accent);
  color: #fff;
  font-weight: 600;
}

.gtp-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
}
.gtp-btn {
  font-family: inherit;
  font-size: 0.78rem;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  cursor: pointer;
}
.gtp-clear {
  /* push Clear to the left; 취소/확인 stay grouped on the right. */
  margin-right: auto;
  background: var(--bg);
  color: var(--muted);
}
.gtp-clear:hover {
  /* same WinUI hover preview as the year cells: accent fill + white text (white
     alone would be invisible on the light-theme --bg). */
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.gtp-dismiss {
  background: var(--bg);
  color: var(--muted);
}
.gtp-dismiss:hover {
  /* same WinUI hover preview as 지우기/clear + the year cells: accent fill +
     white text (white alone would be invisible on the light-theme --bg). */
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.gtp-accept {
  background: var(--accent);
  color: #fff;
  border-color: var(--accent);
}
.gtp-accept:hover {
  filter: brightness(1.08);
}

/* P3.3-028: themed warning popup (window.vcaGraphWarning) for invalid filter
   input — e.g. the Time filter 최소 > 최대. A NON-modal alertdialog centered on
   the viewport, danger-toned, tokens only (no focus trap; the JS restores focus
   on dismiss). Sits above the .gtp-flyout (z 1000). */
.gw-box {
  position: fixed;
  z-index: 1001;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  align-items: center;
  gap: var(--space-2);
  max-width: min(92vw, 30em);
  padding: var(--space-3) var(--space-4);
  background: var(--surface-raised);
  color: var(--text);
  border: 1px solid var(--danger);
  border-left: 4px solid var(--danger);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-card, 0 8px 28px rgba(0, 0, 0, 0.35));
}
/* the box defaults to display:flex, so the UA [hidden] { display:none } would
   not win — restore it explicitly (mirrors .gtp-flyout[hidden]). */
.gw-box[hidden] {
  display: none;
}
.gw-icon {
  flex: 0 0 auto;
  color: var(--danger);
  font-size: 1.1rem;
  line-height: 1;
}
.gw-msg {
  flex: 1 1 auto;
  margin: 0;
  font-size: 0.82rem;
  line-height: 1.45;
}
.gw-ok {
  flex: 0 0 auto;
  font-family: inherit;
  font-size: 0.78rem;
  color: var(--text);
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-3);
  cursor: pointer;
}
.gw-ok:hover {
  border-color: var(--danger);
}
.gw-ok:focus-visible {
  outline: none;
  border-color: var(--danger);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--danger) 35%, transparent);
}
