/* The frame every feature is mounted into: the reset, the page, the bar
   across the top and the nav down the side. Nothing here is any one
   feature's - what a feature draws lives with the feature. */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* 'hidden' means hidden, whatever display the element is given elsewhere - a
   flex container would otherwise ignore the attribute entirely. */
[hidden] { display: none !important; }

html { scroll-behavior: smooth; }

body {
  font-family: var(--font-sans);
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
  font-size: 14px;
  line-height: 1.6;
  overflow-x: hidden;
  background-image:
    radial-gradient(ellipse 80% 50% at 20% 10%, rgba(61,147,203,0.06) 0%, transparent 60%),
    radial-gradient(ellipse 60% 40% at 80% 90%, rgba(139,92,246,0.05) 0%, transparent 60%);
}

/* Ambient background */
body::before {
  content: '';
  position: fixed;
  top: -40%;
  left: -20%;
  width: 80vw;
  height: 80vw;
  background: radial-gradient(circle, rgba(37,99,235,0.07) 0%, transparent 65%);
  pointer-events: none;
  z-index: 0;
}
body::after {
  content: '';
  position: fixed;
  bottom: -30%;
  right: -15%;
  width: 60vw;
  height: 60vw;
  background: radial-gradient(circle, rgba(139,92,246,0.05) 0%, transparent 65%);
  pointer-events: none;
  z-index: 0;
}

/* ─── MAIN ─── */
.main {
  max-width: 860px;
  margin: 0 auto 0 var(--nav-w);
}
/* The library reads in two columns - the outline beside the part being edited
   - so it takes the width the prose features cap. */
.main-documents { max-width: none; }


/* ─── TOP BAR ───
   The shell's, not any one feature's: the mark and the title at one end, the
   showing feature's slot between, the account control's place at the other.
   It stands outside the view, so it is given the view's own box here - the
   content and what heads it line up down one edge. */
.top-bar {
  position: sticky;
  top: 0;
  z-index: 15;
  max-width: 860px;
  margin: 0 auto 0 var(--nav-w);
  background: rgba(15,17,23,0.95);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
  padding: 14px 40px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
}
/* The library reads in two columns, so its bar takes the width its view does
   (see .main-documents). Said on the body because the bar is not in the view
   to be told by it. */
body[data-feature="documents"] .top-bar { max-width: none; }

/* The feature's own end of the bar. It is not a box of its own: what a feature
   puts here - the questionnaire's progress and running score, a view's actions
   - sits in the bar's row directly, spaced by the bar, exactly as it did when
   each feature drew the whole bar itself. */
.top-bar-slot { display: contents; }
/* The mark and the menu's title, set close enough to read as one label. */
.top-bar-logo {
  font-size: 15px;
  color: var(--text);
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 8px;
}
/* The menu's title, in the brand's blue beside the mark that carries it. Cased
   and tracked as the sidebar's heading is, so the two read as one name for one
   thing. */
.top-bar-menu {
  flex-shrink: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
}
.top-bar-center {
  flex: 1;
  max-width: 320px;
}

/* Every button a bar carries - the library's actions, the conversation's, the
   results' printer - takes the corner the lists and fields take, so a bar and
   what is under it read as one surface. The one rule for all of them: `.btn`
   itself keeps the page's own corner, which is what the views use. */
.top-bar .btn { border-radius: var(--radius-sm); }

/* A slot's actions, set in a row. The bar being the shell's, so is this: the
   library puts three here and the conversation one, and they line up the same
   way for both. */
.top-bar-actions { display: flex; gap: 8px; }

/* The results bar's action, held at its right end by the bar's own spacing.
   A printer and nothing more, the sentence it stands for being left to its
   title - so the button is square around the mark. */
.top-bar-action {
  display: flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  padding: 8px;
}
/* A mark drawn in line, so it takes its control's colour through the control's
   states. Whoever uses one gives it its size and its weight; the results'
   printer and the conversation's send key both do. */
.icon {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.icon-print {
  width: 18px;
  height: 18px;
  stroke-width: 1.8;
}

/* ─── CONSENT NOTICE ───
   The frame's other edge: the session cookie disclosed once, across the foot of
   the content the way the bar crosses its head - same ground, same blur, same
   gutters - so the two read as the shell's own and not as something a feature
   put there. Above the content and below the drawer's scrim (z-25): opening
   the nav covers this along with everything else it covers. */
.consent-notice {
  position: fixed;
  left: var(--nav-w);
  right: 0;
  bottom: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 14px 40px;
  background: rgba(15,17,23,0.95);
  backdrop-filter: blur(10px);
  border-top: 1px solid var(--border);
}
.consent-text {
  color: var(--text2);
  font-size: 13px;
}
/* The bar's corner, for the same reason the bar's buttons take it: a strip
   against the page's edge is not a place for the view's rounder controls. */
.consent-notice .btn {
  flex-shrink: 0;
  border-radius: var(--radius-sm);
}

/* ─── SIDE NAV ───
   An accordion of the features: each name with that feature's own panel under
   it, and the showing feature's the one section that is expanded. Fixed beside
   the content while there is room for it; off-canvas behind the burger when
   there is not. */
.side-nav {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: var(--nav-w);
  z-index: 30;
  display: flex;
  flex-direction: column;
  padding: 18px 10px;
  background: rgba(15,17,23,0.97);
  backdrop-filter: blur(12px);
  border-right: 1px solid var(--border);
  /* The expanded panel scrolls, not the drawer: every feature's name stays
     where it is however long the showing one's list of items gets. */
  overflow: hidden;
  transition: transform 0.25s cubic-bezier(0.4,0,0.2,1);
}
/* An item is a link to the position it names, so the position can be copied
   and not only reached - the underline a link would otherwise carry is not
   wanted, the item's own box being what shows it is one. */
.nav-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 6px 12px;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  text-decoration: none;
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 500;
  color: var(--text3);
  text-align: left;
  cursor: pointer;
  transition: all 0.15s;
}
/* Keyboard focus has to be visible: with the roving tabindex the arrow keys
   move it, and the outline is the only sign of where it went. */
.nav-item:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: -2px;
}
.nav-item:hover { background: var(--surface2); color: var(--text); }
/* Only the check-mark goes green: the label reads the same done or not, so the
   nav stays one colour and the mark alone carries the state. */
.nav-item.done::after {
  content: '✓';
  font-size: 13px;
  font-weight: 700;
  color: var(--D);
}
/* A finished area needs no tally - the check-mark takes the count's place. */
.nav-item.done .nav-item-count { display: none; }
.nav-item.active { background: rgba(61,147,203,0.12); color: var(--accent); }
/* A fixed column, so every label starts at the same place - whatever the
   icon's own width, and whether the item has one at all. */
.nav-item-icon { flex-shrink: 0; width: 18px; font-size: 15px; }
.nav-item-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* The area's progress, held against the right edge by the name's flex.
   It takes the item's own colour, so it follows the active and done states. */
.nav-item-count {
  flex-shrink: 0;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}
.nav-item-res {
  color: var(--accent);
  font-weight: 600;
  text-transform: uppercase;
}

/* Burger - only ever shown while the nav is off-canvas. It sits outside the
   top bar, over the bar's left edge, so that hiding the bar on the results
   leaves the areas reachable. Under the scrim, as it has always been: while
   the nav is open, the scrim is what a click outside it lands on. */
.nav-toggle {
  display: none;
  position: fixed;
  top: 14px;
  left: 16px;
  z-index: 20;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  flex-shrink: 0;
  width: 48px; height: 48px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 13px;
  background: var(--surface2);
  cursor: pointer;
}
.nav-toggle span {
  display: block;
  width: 22px; height: 3px;
  margin: 0 auto;
  border-radius: 3px;
  background: var(--text2);
  transition: transform 0.2s, opacity 0.2s;
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(9px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }

.nav-scrim {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 25;
  background: rgba(0,0,0,0.5);
  backdrop-filter: blur(2px);
}

/* ─── INNER PAD ─── */
/* The one place the content's spacing from the page is set - side gutters and
   vertical rhythm both. Padding, not a child's margin, so nothing collapses
   out of it and the first block starts where it looks like it starts. */
.inner-pad { padding: 24px 30px 48px; }


@media (max-width: 700px) {
  .top-bar { padding: 12px 16px; }
  .top-bar-center { display: none; }
  /* No room for a row of them at this width. What is dropped is the actions
     on the thing being shown; a control that switches what the view *is* -
     the library's way into editing - is not one of those and stays. */
  .top-bar-actions > :not(.documents-mode) { display: none; }
  .inner-pad { padding: 20px 16px 64px; }
  /* Two lines of it beside a button leaves neither room: the notice reads
     across the width and the acknowledgement sits under it. */
  .consent-notice {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 16px;
  }
}

/* Not enough width for the nav beside the content: it slides in over it. */
@media (max-width: 900px) {
  .main, .top-bar { margin-left: 0; }
  .consent-notice { left: 0; }
  .side-nav {
    transform: translateX(-100%);
    box-shadow: 0 0 40px rgba(0,0,0,0.5);
  }
  .side-nav.open { transform: translateX(0); }
  .nav-scrim.open { display: block; }
  .nav-toggle { display: flex; }
  /* Room for the floating burger, beside the logo - either view's bar, since
     both carry one. */
  .top-bar-logo { padding-left: 58px; }
}

/* ─── PRINT ───
   The frame does not go on paper: the bar, the drawer and the burger are ways
   around the application, and a sheet is not one. What is left takes the
   page's own margin as its gutter. The palette a printed view reads in is that
   view's own (see the questionnaire's results). */
@media print {
  .top-bar, .side-nav, .nav-toggle, .nav-scrim,
  .consent-notice { display: none !important; }
  .main, .top-bar { margin: 0 !important; max-width: none; }
  .inner-pad { padding: 0; }
  body { background: #FFFFFF; background-image: none; }
  body::before, body::after { display: none; }
}

/* app2: generated markup style separation */
.top-score-max {
  color: var(--text3);
  font-size: 11px;
  font-weight: 400;
}

.score-a { --score-color: var(--A); }
.score-b { --score-color: var(--B); }
.score-c { --score-color: var(--C); }
.score-d { --score-color: var(--D); }
.score-e { --score-color: var(--E); }
.score-muted { --score-color: var(--text3); }


/* ─── FEATURE ACCORDION ───
   The level-1 menu, and the whole of the drawer: a section per feature, each
   the feature's name over that feature's own panel. One section is expanded -
   the feature the page is on - so switching feature is what opens a section
   and closes the one that was open. The name stays a quiet link rather than
   taking the items' full treatment: what is being switched between is the
   application's parts, not the part's contents. */
.side-nav-accordion {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}
/* Collapsed, a section is its name and nothing else. Expanded, it takes what
   room its items want and no more - and gives room back rather than push the
   names under it off the drawer, its panel scrolling instead. */
.feature-section {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
}
/* Only the open one gives room back - the shut names are a name's height each
   and stay it, whatever is open above them. */
.feature-section.expanded {
  flex-shrink: 1;
  min-height: 0;
}
.feature-section + .feature-section { border-top: 1px solid var(--border); }

.feature-item {
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  color: var(--text3);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-decoration: none;
  transition: background 0.15s, color 0.15s;
}
.feature-item:hover { background: var(--surface2); color: var(--text2); }
.feature-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
/* The feature the page is on, in the brand's blue - it is the only name the
   drawer gives that feature, and it keeps saying so with its section folded
   shut: what is showing in the view and what stands open in the drawer are two
   things now, and a name that dimmed on being folded would lose the first. */
.feature-item.active { background: var(--surface2); color: var(--accent); }
.feature-item-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Which way the section is folded, in the one mark that says it: pointing at
   the name while the panel is shut, and down into it once it is open. It turns
   on the state the name itself carries, so the mark cannot say one thing while
   the assistive tree says another. */
.feature-item-caret {
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  opacity: 0.65;
  transform: rotate(-45deg);
  transition: transform 0.2s ease;
}
.feature-item[aria-expanded="true"] .feature-item-caret { transform: rotate(45deg); }

/* The open feature's items, indented under the name they belong to. */
.feature-panel { display: none; }
.feature-panel.expanded {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-height: 0;
  padding: 4px 0 8px 8px;
  overflow-y: auto;
  animation: panel-open 0.18s ease;
}
@keyframes panel-open {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

/* What a feature not yet built says in place of itself. */
.placeholder {
  padding: 48px 0;
  color: var(--text3);
  font-size: 14px;
  text-align: center;
}

/* ─── BUTTONS ───
   Every feature's buttons: the questionnaire's, the documents library's, and the bar
   action any view brings with it. Moved here when the third one needed them. */
.btn {
  padding: 11px 22px;
  border-radius: var(--radius);
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  border: none;
  transition: all 0.15s;
}
.btn-primary {
  background: linear-gradient(135deg, var(--accent), #7C3AED);
  color: white;
  box-shadow: 0 4px 14px rgba(61,147,203,0.25);
}
.btn-primary:hover {
  opacity: 0.9;
  box-shadow: 0 6px 24px rgba(61,147,203,0.4);
  transform: translateY(-1px);
}
.btn-ghost {
  background: var(--surface2);
  color: var(--text2);
  border: 1px solid var(--border);
}
.btn-ghost:hover {
  background: var(--surface3);
  border-color: var(--border2); }

/* An action that cannot be undone does not look like the others. */
.btn-danger {
  background: var(--surface2);
  color: var(--A);
  border: 1px solid color-mix(in srgb, var(--A) 40%, transparent);
}
.btn-danger:hover {
  background: color-mix(in srgb, var(--A) 14%, var(--surface2));
  border-color: var(--A);
}

/* ─── SPINNER ───
   What a run that takes minutes shows while it takes them. The questionnaire's
   report and the documents library's processing both wait on the same kind of
   work. */
.spinner {
  width: 48px; height: 48px;
  border: 4px solid var(--surface3);
  border-top: 4px solid var(--accent);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}
@keyframes spin {
  to { transform: rotate(360deg); }
}


/* ─── DIALOG ───
   What a feature asks the visitor through: a deletion says what it is
   deleting, and the two features that ask, ask the same way. */
.dialog-overlay {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(0,0,0,0.75);
  backdrop-filter: blur(6px);
}
.dialog {
  width: 100%;
  max-width: 420px;
  padding: 28px;
  border: 1px solid var(--border2);
  border-radius: var(--radius-xl);
  background: var(--surface);
  box-shadow: 0 24px 60px rgba(0,0,0,0.5);
}
.dialog p { margin-bottom: 18px; font-size: 14px; }
.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
.dialog-options {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 18px;
}

