/* ==========================================================================
   Trading Journal — component styles.
   No inline styles are used anywhere in the application; every rule lives here
   and consumes the design tokens declared in tokens.css.
   ========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background-color: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--font-size-base);
  line-height: var(--line-height-body);
  letter-spacing: var(--letter-spacing-body);
  word-spacing: var(--word-spacing-body);
}

h1,
h2,
h3,
h4 {
  line-height: var(--line-height-heading);
  margin: 0 0 var(--space-3);
  font-weight: 650;
  letter-spacing: -0.01em;
}

h1 {
  font-size: var(--font-size-3xl);
}
h2 {
  font-size: var(--font-size-2xl);
}
h3 {
  font-size: var(--font-size-xl);
}
h4 {
  font-size: var(--font-size-lg);
}

p {
  margin: 0 0 var(--space-4);
  max-width: var(--prose-max);
}

a {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}

a:hover {
  color: var(--color-accent-hover);
}

/* --- Focus appearance (SC 2.4.13): 2px ring plus 2px offset halo --------- */
:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Scroll padding keeps focused controls clear of the sticky header (SC 2.4.12) */
html {
  scroll-padding-top: calc(var(--header-height) + var(--space-5));
  scroll-padding-bottom: var(--space-6);
}

/* --- Utility ------------------------------------------------------------- */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: -4rem;
  z-index: 100;
  padding: var(--space-3) var(--space-4);
  background-color: var(--color-surface);
  color: var(--color-text);
  border: 2px solid var(--color-focus);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: top var(--duration-fast) var(--easing);
}

.skip-link:focus {
  top: var(--space-3);
}

.stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.stack-tight {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}

.row-end {
  justify-content: flex-end;
}

.muted {
  color: var(--color-text-muted);
}

.text-sm {
  font-size: var(--font-size-sm);
}

.numeric {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/* --- Application shell --------------------------------------------------- */
.app-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background-color: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  min-height: var(--header-height);
  display: flex;
  align-items: center;
}

.app-header__inner {
  width: 100%;
  max-width: var(--content-max);
  margin: 0 auto;
  padding: var(--space-3) var(--space-5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: center;
  justify-content: space-between;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: 700;
  font-size: var(--font-size-lg);
  color: var(--color-text);
  text-decoration: none;
}

.brand:hover {
  color: var(--color-text);
}

.brand__mark {
  display: grid;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-sm);
  background-color: var(--color-accent-soft);
  color: var(--color-accent);
}

.primary-nav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  list-style: none;
  margin: 0;
  padding: 0;
}

.primary-nav a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--min-target);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-text);
  text-decoration: none;
  font-weight: 500;
  border: 1px solid transparent;
}

.primary-nav a:hover {
  background-color: var(--color-surface-raised);
}

/* The abbreviated wording is only shown in the narrow bottom bar on phones. */
.nav-label-short {
  display: none;
}

/* Current location is conveyed by text, weight and a bar — not colour alone */
.primary-nav a[aria-current='page'] {
  background-color: var(--color-accent-soft);
  color: var(--color-text);
  font-weight: 650;
  border-color: var(--color-accent);
}

.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.app-main {
  max-width: var(--content-max);
  margin: 0 auto;
  padding: var(--space-6) var(--space-5) var(--space-8);
}

.page-header {
  margin-bottom: var(--space-6);
}

.page-header__meta {
  color: var(--color-text-muted);
  max-width: var(--prose-max);
}

.app-footer {
  border-top: 1px solid var(--color-border);
  padding: var(--space-5);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.app-footer__inner {
  max-width: var(--content-max);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: space-between;
}

/* --- Breadcrumbs (SC 2.4.8 Location) ------------------------------------ */
.breadcrumbs {
  margin-bottom: var(--space-4);
  font-size: var(--font-size-sm);
}

.breadcrumbs ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.breadcrumbs li + li::before {
  content: '/';
  margin-right: var(--space-2);
  color: var(--color-text-muted);
}

/* --- Cards and grid ----------------------------------------------------- */
.grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(12, minmax(0, 1fr));
}

.col-3 {
  grid-column: span 3;
}
.col-4 {
  grid-column: span 4;
}
.col-6 {
  grid-column: span 6;
}
.col-8 {
  grid-column: span 8;
}
.col-12 {
  grid-column: span 12;
}

@media (max-width: 60rem) {
  .col-3,
  .col-4 {
    grid-column: span 6;
  }
  .col-6,
  .col-8 {
    grid-column: span 12;
  }
}

@media (max-width: 40rem) {
  .col-3,
  .col-4,
  .col-6 {
    grid-column: span 12;
  }
}

.card {
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: var(--shadow-sm);
}

.card__header {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: var(--space-4);
}

.card__title {
  margin: 0;
  font-size: var(--font-size-lg);
}

/* --- Metric cards ------------------------------------------------------- */
.metric {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.metric__label {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.metric__value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: var(--font-size-2xl);
  font-weight: 650;
}

.metric__hint {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* Profit and loss always pair colour with an icon and a word */
.value-positive {
  color: var(--color-profit);
}
.value-negative {
  color: var(--color-loss);
}
.value-neutral {
  color: var(--color-text-muted);
}

.trend {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

/* --- Buttons ------------------------------------------------------------ */
.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--min-target);
  min-width: var(--min-target);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border-strong);
  background-color: var(--color-surface);
  color: var(--color-text);
  font: inherit;
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: background-color var(--duration-fast) var(--easing);
}

.button:hover {
  background-color: var(--color-surface-raised);
  color: var(--color-text);
}

.button--primary {
  background-color: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-text-inverse);
}

.button--primary:hover {
  background-color: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
  color: var(--color-text-inverse);
}

.button--danger {
  border-color: var(--color-loss);
  color: var(--color-loss);
  background-color: var(--color-surface);
}

.button--danger:hover {
  background-color: var(--color-loss-soft);
}

.button--quiet {
  border-color: transparent;
  background-color: transparent;
}

.button--quiet:hover {
  background-color: var(--color-surface-raised);
}

.button--small {
  min-height: var(--min-target);
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-size-sm);
}

.button[disabled],
.button[aria-disabled='true'] {
  opacity: 0.6;
  cursor: not-allowed;
}

.button-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* --- Forms -------------------------------------------------------------- */
.form-grid {
  display: grid;
  gap: var(--space-4);
  grid-template-columns: repeat(12, minmax(0, 1fr));
}

.field {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  grid-column: span 4;
}

.field--wide {
  grid-column: span 8;
}

.field--full {
  grid-column: span 12;
}

@media (max-width: 60rem) {
  .field,
  .field--wide {
    grid-column: span 12;
  }
}

.field__label {
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.field__requirement {
  font-weight: 500;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

.field__help {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  margin: 0;
  max-width: var(--prose-max);
}

.field__error {
  font-size: var(--font-size-sm);
  color: var(--color-loss);
  font-weight: 600;
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
}

input[type='text'],
input[type='email'],
input[type='password'],
input[type='number'],
input[type='date'],
input[type='datetime-local'],
input[type='url'],
input[type='file'],
select,
textarea {
  width: 100%;
  min-height: var(--min-target);
  padding: var(--space-2) var(--space-3);
  font: inherit;
  color: var(--color-text);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
}

textarea {
  min-height: 7rem;
  resize: vertical;
  line-height: var(--line-height-body);
}

input[aria-invalid='true'],
select[aria-invalid='true'],
textarea[aria-invalid='true'] {
  border-color: var(--color-loss);
  border-width: 2px;
}

fieldset {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin: 0;
}

legend {
  padding: 0 var(--space-2);
  font-weight: 650;
}

.radio-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.radio-option {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--min-target);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.radio-option:has(input:checked) {
  border-color: var(--color-accent);
  background-color: var(--color-accent-soft);
  font-weight: 600;
}

input[type='radio'],
input[type='checkbox'] {
  width: 1.25rem;
  height: 1.25rem;
  accent-color: var(--color-accent);
}

.checkbox-row {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--min-target);
}

/* --- Error summary (SC 3.3.1 / 3.3.6) ---------------------------------- */
.alert {
  border: 2px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
}

.alert__body {
  flex: 1 1 auto;
}

.alert__body > :last-child {
  margin-bottom: 0;
}

.alert--error {
  border-color: var(--color-loss);
  background-color: var(--color-loss-soft);
}

.alert--success {
  border-color: var(--color-profit);
  background-color: var(--color-profit-soft);
}

.alert--info {
  border-color: var(--color-info-text);
  background-color: var(--color-info-soft);
}

.alert--warning {
  border-color: var(--color-warning-text);
  background-color: var(--color-warning-soft);
}

.alert ul {
  margin: var(--space-2) 0 0;
  padding-left: var(--space-5);
}

/* --- Tables ------------------------------------------------------------- */
.table-scroll {
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

/*
 * Only overflowing tables become focusable, and when they do the focus ring
 * must sit inside the rounded border rather than be clipped by the scroll
 * container.
 */
.table-scroll:focus-visible {
  outline: 3px solid var(--color-focus);
  outline-offset: -3px;
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--font-size-sm);
}

caption {
  text-align: left;
  padding: var(--space-3) var(--space-4);
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

th,
td {
  padding: var(--space-3);
  text-align: left;
  border-bottom: 1px solid var(--color-border);
  vertical-align: top;
}

/*
 * The ticker in each row is how a trade is opened, so it is a primary
 * target rather than an incidental link in a sentence, and it must clear the
 * 24px floor (SC 2.5.8). A short ticker such as "KO" is only about 22px
 * wide, so the tappable area is padded out instead of relying on the text.
 */
tbody th a,
tbody td a {
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  min-height: 24px;
  min-width: 24px;
  padding-block: var(--space-1);
}

thead th {
  position: sticky;
  top: 0;
  background-color: var(--color-surface-raised);
  z-index: 1;
  font-weight: 650;
  white-space: nowrap;
}

tbody tr:nth-child(even) {
  background-color: var(--color-surface-raised);
}

tbody tr:hover {
  background-color: var(--color-accent-soft);
}

td.numeric,
th.numeric {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

.table-sort {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--min-target);
  padding: var(--space-1) var(--space-2);
  background: none;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: inherit;
  font: inherit;
  font-weight: 650;
  cursor: pointer;
}

.table-sort:hover {
  background-color: var(--color-surface-sunken);
}

.row-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

/* --- Badges ------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.125rem var(--space-2);
  border-radius: 999px;
  border: 1px solid var(--color-border-strong);
  font-size: var(--font-size-xs);
  font-weight: 650;
  white-space: nowrap;
}

.badge--profit {
  border-color: var(--color-profit);
  color: var(--color-profit);
  background-color: var(--color-profit-soft);
}

.badge--loss {
  border-color: var(--color-loss);
  color: var(--color-loss);
  background-color: var(--color-loss-soft);
}

.badge--neutral {
  color: var(--color-text-muted);
}

.badge--accent {
  border-color: var(--color-accent);
  color: var(--color-accent);
  background-color: var(--color-accent-soft);
}

/* --- Charts ------------------------------------------------------------- */
.chart-frame {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  background-color: var(--color-surface);
}

.chart-svg {
  width: 100%;
  height: auto;
  display: block;
}

.chart-axis-label {
  font-size: 11px;
  fill: var(--color-text-muted);
}

.chart-line {
  fill: none;
  stroke: var(--color-accent);
  stroke-width: 2.5;
  stroke-linejoin: round;
}

.chart-area {
  fill: var(--color-accent-soft);
  opacity: 0.7;
}

.chart-grid {
  stroke: var(--color-border);
  stroke-width: 1;
}

.chart-zero {
  stroke: var(--color-border-strong);
  stroke-width: 1.5;
  stroke-dasharray: 4 3;
}

.chart-bar--positive {
  fill: var(--color-profit);
}

.chart-bar--negative {
  fill: var(--color-loss);
}

.chart-point {
  fill: var(--color-accent);
}

/* Data-table fallback for every chart (SC 1.1.1) */
.chart-data-toggle {
  margin-top: var(--space-3);
}

details.data-fallback {
  margin-top: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
}

details.data-fallback > summary {
  cursor: pointer;
  font-weight: 650;
  min-height: var(--min-target);
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

/* --- Calendar heatmap --------------------------------------------------- */
.heatmap {
  display: grid;
  grid-template-columns: repeat(7, minmax(2.75rem, 1fr));
  gap: var(--space-1);
  list-style: none;
  margin: 0;
  padding: 0;
}

.heatmap__weekday {
  font-size: var(--font-size-xs);
  font-weight: 650;
  color: var(--color-text-muted);
  text-align: center;
  padding-bottom: var(--space-1);
}

.heatmap__cell {
  min-height: var(--min-target);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-1);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  font-size: var(--font-size-xs);
  color: var(--color-text);
}

/*
 * A day with no closed trades is set back with a dashed, lighter border
 * rather than by fading the whole tile. Reducing opacity would have dimmed
 * the date itself below a readable contrast, and the date is the one thing
 * on an empty tile a reader still needs.
 */
.heatmap__cell--empty {
  border-style: dashed;
  border-color: var(--color-border-strong);
  background-color: transparent;
}

.heatmap__day {
  font-weight: 650;
}

.heatmap__amount {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}

/*
 * No tier switches to inverted text. The fills are picked so the ordinary
 * body colour clears 7:1 on all of them, which keeps one reading colour
 * across the whole calendar instead of flipping at the darkest tiles.
 */
.heat-3-loss {
  background-color: var(--heat-loss-3);
}
.heat-2-loss {
  background-color: var(--heat-loss-2);
}
.heat-1-loss {
  background-color: var(--heat-loss-1);
}
.heat-0 {
  background-color: var(--heat-zero);
}
.heat-1-gain {
  background-color: var(--heat-gain-1);
}
.heat-2-gain {
  background-color: var(--heat-gain-2);
}
.heat-3-gain {
  background-color: var(--heat-gain-3);
}

.heatmap-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  list-style: none;
  padding: 0;
  margin: var(--space-3) 0 0;
  font-size: var(--font-size-sm);
}

.heatmap-legend li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.heatmap-legend__swatch {
  width: 1rem;
  height: 1rem;
  border-radius: 3px;
  border: 1px solid var(--color-border-strong);
}

/* --- Dialogs (keyboard operable, no forced modals) --------------------- */
dialog {
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  max-width: 34rem;
  width: calc(100% - 2rem);
  background-color: var(--color-surface);
  color: var(--color-text);
  box-shadow: var(--shadow-md);
}

dialog::backdrop {
  background-color: rgba(6, 10, 14, 0.55);
}

.dialog__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: flex-end;
  margin-top: var(--space-5);
}

/* --- Toasts: dismissible, never auto-hiding (SC 2.2.4) ---------------- */
.toast-region {
  position: fixed;
  right: var(--space-4);
  bottom: var(--space-4);
  z-index: 60;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  max-width: min(26rem, calc(100vw - 2rem));
}

.toast {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  border: 2px solid var(--color-border-strong);
  background-color: var(--color-surface);
  box-shadow: var(--shadow-md);
}

.toast--success {
  border-color: var(--color-profit);
  background-color: var(--color-profit-soft);
}

.toast--error {
  border-color: var(--color-loss);
  background-color: var(--color-loss-soft);
}

.toast__body {
  flex: 1 1 auto;
  font-size: var(--font-size-sm);
}

/* --- Glossary (SC 3.1.3 / 3.1.4) -------------------------------------- */
.term {
  border-bottom: 1px dotted var(--color-border-strong);
  cursor: help;
  text-decoration: none;
}

.term-definition {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background-color: var(--color-surface-raised);
  padding: var(--space-3);
  font-size: var(--font-size-sm);
  max-width: var(--prose-max);
}

.help-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--min-target);
  height: var(--min-target);
  border: 1px solid var(--color-border-strong);
  border-radius: 999px;
  background-color: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
}

.help-toggle:hover {
  background-color: var(--color-surface-raised);
}

/* --- Filters ----------------------------------------------------------- */
/*
 * The 11rem floor is a preference, not a hard minimum: on a 320px phone the
 * available width is narrower than that, and a plain minmax() would force the
 * track wider than its container and push the whole page sideways. Clamping
 * the floor to the space actually available lets the filters fall to a single
 * column instead (SC 1.4.10 Reflow).
 */
.filter-bar {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
  align-items: end;
}

/*
 * Fields carry a 'span 4' meant for the twelve-column form grid. Inside the
 * auto-fit filter bar that span forces four tracks to exist, so each field
 * stretched to roughly 354px and pushed a 320px phone sideways. Here each
 * field occupies exactly one track and the auto-fit rule decides how many
 * tracks fit (SC 1.4.10 Reflow).
 */
.filter-bar > .field,
.filter-bar > .field--wide,
.filter-bar > .field--full {
  grid-column: auto;
  min-width: 0;
}

.filter-bar__actions {
  display: flex;
  gap: var(--space-2);
  align-items: end;
}

/* --- Auth pages -------------------------------------------------------- */
.auth-layout {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--space-6) var(--space-4);
}

.auth-card {
  width: 100%;
  max-width: 30rem;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-md);
}

.auth-card__brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
  font-weight: 700;
  font-size: var(--font-size-lg);
}

.auth-tabs {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-5);
  border-bottom: 1px solid var(--color-border);
}

.auth-tab {
  min-height: var(--min-target);
  padding: var(--space-2) var(--space-3);
  border: 1px solid transparent;
  border-bottom: 3px solid transparent;
  background: none;
  color: var(--color-text);
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}

.auth-tab[aria-selected='true'] {
  border-bottom-color: var(--color-accent);
  color: var(--color-text);
}

.auth-tab:hover {
  background-color: var(--color-surface-raised);
}

/* --- Pagination -------------------------------------------------------- */
.pagination {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  justify-content: space-between;
  margin-top: var(--space-4);
}

/* --- Progress / meters ------------------------------------------------- */
.bar-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* The label track yields before the page does, so nothing spills sideways. */
.bar-list__row {
  display: grid;
  grid-template-columns: minmax(min(8rem, 50%), 1fr) 4rem;
  gap: var(--space-3);
  align-items: center;
}

.bar-track {
  height: 0.75rem;
  border-radius: 999px;
  background-color: var(--color-surface-sunken);
  border: 1px solid var(--color-border);
  overflow: hidden;
}

.bar-fill {
  height: 100%;
  background-color: var(--color-accent);
}

/* --- Print ------------------------------------------------------------- */
@media print {
  .app-header,
  .app-footer,
  .toast-region,
  .no-print {
    display: none !important;
  }
  body {
    background: #ffffff;
    color: #000000;
  }
}

/* Bar fill widths are applied by app.js from data-width, keeping markup free of
   inline styles while still allowing data-driven proportions. */
.bar-fill--negative {
  background-color: var(--color-loss);
}

.bar-fill--positive {
  background-color: var(--color-accent);
}

[data-role='bar-label'] {
  justify-content: space-between;
  font-size: var(--font-size-sm);
}

[data-role='page-heading-row'] {
  justify-content: space-between;
  align-items: flex-start;
}

/* ==========================================================================
   Quick-fill and prepopulated input
   Buttons that put a known value into a field. Every one meets the enhanced
   44x44 CSS pixel target size (SC 2.5.5) and carries visible text, never an
   icon on its own.
   ========================================================================== */
.quick-fill {
  margin-top: var(--space-2);
}

.quick-fill__legend {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.quick-fill__list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--min-target);
  min-width: var(--min-target);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-raised);
  color: var(--color-text);
  font: inherit;
  font-size: var(--font-size-sm);
  font-weight: 500;
  cursor: pointer;
  text-align: center;
}

.chip:hover {
  background-color: var(--color-accent-soft);
  border-color: var(--color-accent);
}

.chip[aria-pressed='true'] {
  background-color: var(--color-accent-soft);
  border-color: var(--color-accent);
  font-weight: 650;
}

/* Note printed under a field once a ticker is recognised. */
.field__note {
  margin: var(--space-2) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  min-height: 1.5em;
}

.field__note:not(:empty)::before {
  content: '';
}

/* --- Recently traded instruments ---------------------------------------- */
.recent-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(14rem, 100%), 1fr));
  gap: var(--space-3);
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
}

.recent-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  width: 100%;
  min-height: var(--min-target);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background-color: var(--color-surface-raised);
  color: var(--color-text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.recent-card:hover {
  border-color: var(--color-accent);
  background-color: var(--color-accent-soft);
}

.recent-card__ticker {
  font-family: var(--font-mono);
  font-size: var(--font-size-lg);
  font-weight: 600;
}

.recent-card__name {
  font-weight: 500;
}

.recent-card__meta {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* --- Collapsible filters ------------------------------------------------ */
.filter-disclosure__summary {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--min-target);
  cursor: pointer;
  list-style: none;
}

.filter-disclosure__summary::-webkit-details-marker {
  display: none;
}

.filter-disclosure__summary::after {
  content: 'Show';
  margin-left: auto;
  font-size: var(--font-size-sm);
  font-weight: 500;
  color: var(--color-accent);
}

.filter-disclosure[open] > .filter-disclosure__summary::after {
  content: 'Hide';
}

.filter-disclosure__summary .card__title {
  margin: 0;
}

.filter-disclosure[open] > .filter-disclosure__summary {
  margin-bottom: var(--space-4);
}

/* --- Form action bar ---------------------------------------------------- */
.form-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
}

.form-actions__status {
  flex-basis: 100%;
}

/* ==========================================================================
   Mobile layout
   The application is built for one-handed use on a phone first: navigation sits
   within thumb reach at the bottom of the screen, wide tables become stacked
   records that keep their column names, and every control stays at least
   44x44 CSS pixels (SC 2.5.5 Target Size, Enhanced).
   ========================================================================== */

/* Tablets and small laptops: navigation drops to its own row. */
@media (max-width: 64rem) {
  .app-header__inner {
    padding: var(--space-3) var(--space-4);
  }

  .primary-nav {
    order: 3;
    width: 100%;
  }

  .primary-nav ul {
    gap: var(--space-1);
  }
}

@media (max-width: 48rem) {
  .app-main {
    padding: var(--space-5) var(--space-4) var(--space-6);
  }

  .card {
    padding: var(--space-4);
  }

  h1 {
    font-size: var(--font-size-xl);
  }

  .card__header {
    align-items: flex-start;
  }

  /* Heading actions become full-width stacked buttons that are easy to hit. */
  [data-role='page-heading-row'] {
    flex-direction: column;
    align-items: stretch;
  }

  [data-role='page-heading-row'] .row-end {
    justify-content: flex-start;
  }

  .button-group {
    flex-direction: column;
    align-items: stretch;
  }

  .button-group > .button {
    width: 100%;
  }

  .filter-bar {
    grid-template-columns: 1fr;
  }

  .form-grid {
    grid-template-columns: 1fr;
  }

  .recent-list {
    grid-template-columns: 1fr;
  }
}

/* Phones: bottom navigation bar, stacked tables, full-width controls. */
@media (max-width: 40rem) {
  /* --- Header keeps only the brand and sign-out; the nav moves to the foot */
  .app-header {
    min-height: auto;
  }

  .app-header__inner {
    flex-wrap: nowrap;
    gap: var(--space-3);
    padding: var(--space-2) var(--space-3);
  }

  .brand {
    font-size: var(--font-size-base);
  }

  .header-actions__name {
    display: none;
  }

  /*
    The same <nav> element, repositioned as a fixed bottom bar. It is not
    hidden or duplicated, so there is still exactly one main navigation
    landmark and the tab order remains the document order.
  */
  .primary-nav {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 50;
    width: 100%;
    order: initial;
    background-color: var(--color-surface);
    border-top: 1px solid var(--color-border-strong);
    padding: var(--space-1) var(--space-1) calc(var(--space-1) + env(safe-area-inset-bottom, 0px));
    box-shadow: var(--shadow-md);
  }

  .primary-nav ul {
    justify-content: space-around;
    flex-wrap: nowrap;
    gap: 0;
  }

  .primary-nav li {
    flex: 1 1 0;
  }

  .primary-nav a {
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    min-height: 3.25rem;
    padding: var(--space-1);
    font-size: var(--font-size-xs);
    text-align: center;
  }

  /* The full label is kept for assistive technology; the short one is shown. */
  .primary-nav .nav-label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .primary-nav .nav-label-short {
    display: block;
  }

  /* Room for the fixed bar so nothing is trapped underneath it. */
  body {
    padding-bottom: 4.5rem;
  }

  .app-footer {
    padding-bottom: var(--space-6);
  }

  /* --- Stacked tables --------------------------------------------------- */
  /*
    Each row becomes a small record card. The column name is repeated in front
    of every value using the data-label attribute, so a value is never read or
    seen without its heading. The underlying markup is still a real table, so
    screen-reader table navigation keeps working.
  */
  .table--stackable {
    border: 0;
  }

  .table--stackable thead {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
  }

  .table--stackable tr {
    display: block;
    margin-bottom: var(--space-3);
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius-md);
    background-color: var(--color-surface);
    padding: var(--space-2) var(--space-3);
  }

  .table--stackable tbody tr:nth-child(even) {
    background-color: var(--color-surface-raised);
  }

  .table--stackable th,
  .table--stackable td {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-2);
    justify-content: space-between;
    align-items: baseline;
    width: 100%;
    border: 0;
    border-bottom: 1px solid var(--color-border);
    padding: var(--space-2) 0;
    text-align: left;
  }

  .table--stackable tr > :last-child {
    border-bottom: 0;
  }

  .table--stackable th[data-label]::before,
  .table--stackable td[data-label]::before {
    content: attr(data-label);
    flex: 0 0 auto;
    font-weight: 600;
    font-size: var(--font-size-sm);
    color: var(--color-text-muted);
  }

  .table--stackable td.numeric,
  .table--stackable th.numeric {
    text-align: left;
  }

  .table--stackable .row-actions {
    flex-direction: column;
    align-items: stretch;
    width: 100%;
  }

  .table--stackable .row-actions .button,
  .table--stackable .row-actions form,
  .table--stackable .row-actions form .button {
    width: 100%;
  }

  /* Tables that stay tabular still scroll, with a visible hint of more. */
  .table-scroll {
    -webkit-overflow-scrolling: touch;
  }

  /* --- Controls --------------------------------------------------------- */
  input[type='text'],
  input[type='email'],
  input[type='password'],
  input[type='number'],
  input[type='date'],
  input[type='datetime-local'],
  input[type='url'],
  select,
  textarea {
    /* 16px prevents iOS Safari from zooming in when a field is focused. */
    font-size: max(1rem, var(--font-size-base));
    min-height: var(--min-target);
  }

  .button {
    min-height: var(--min-target);
  }

  .button--block-mobile {
    width: 100%;
    justify-content: center;
  }

  .radio-row {
    flex-direction: column;
    align-items: stretch;
  }

  .radio-option {
    min-height: var(--min-target);
  }

  .form-actions {
    flex-direction: column;
    align-items: stretch;
  }

  .form-actions > .button,
  .form-actions > a.button {
    width: 100%;
    justify-content: center;
  }

  /* --- Filters closed by default on the smallest screens ---------------- */
  .filter-disclosure__summary {
    margin-bottom: 0;
  }

  /* --- Charts and calendar ---------------------------------------------- */
  .chart-svg {
    min-height: 12rem;
  }

  /*
    Five columns on a phone rather than seven: each day keeps a readable amount
    of text, and the weekday headings are dropped in favour of the date label
    already inside each cell. The full calendar remains available as a table.
  */
  .heatmap {
    grid-template-columns: repeat(auto-fill, minmax(4.5rem, 1fr));
  }

  .heatmap__weekday {
    display: none;
  }

  .heatmap__cell--empty:empty {
    display: none;
  }

  .heatmap__cell {
    min-height: 3.5rem;
  }

  .heatmap-legend {
    flex-direction: column;
    align-items: flex-start;
  }

  /* --- Dialogs and messages --------------------------------------------- */
  dialog {
    width: calc(100vw - 2 * var(--space-4));
    max-width: none;
    margin: auto var(--space-4);
    padding: var(--space-4);
  }

  .dialog__actions {
    flex-direction: column;
    align-items: stretch;
  }

  .dialog__actions .button {
    width: 100%;
    justify-content: center;
  }

  .toast-region {
    left: var(--space-3);
    right: var(--space-3);
    /* Clear of the fixed navigation bar. */
    bottom: 5rem;
    max-width: none;
  }

  .toast {
    flex-direction: column;
    align-items: stretch;
  }

  .pagination {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-3);
  }

  .breadcrumbs {
    font-size: var(--font-size-xs);
  }

  .app-footer__inner {
    flex-direction: column;
  }

  .metric__value {
    font-size: var(--font-size-xl);
  }
}

/*
  Very narrow phones: the sticky top header would eat too much of the screen,
  so it scrolls away with the page. The bottom navigation bar remains fixed, so
  every destination is still one tap away and SC 2.4.12 is unaffected.
*/
@media (max-width: 26rem) {
  .app-header {
    position: static;
  }

  html {
    scroll-padding-top: var(--space-4);
  }
}

/* Landscape phones have very little height for a sticky header. */
@media (max-height: 26rem) and (orientation: landscape) {
  .app-header {
    position: static;
  }
}

/* The bottom navigation bar is a screen convenience only. */
@media print {
  .primary-nav {
    display: none;
  }
}

/* --- Reduced motion ------------------------------------------------------ */
/*
 * Some readers find movement distracting, and for a few it can trigger
 * nausea or migraine. When the operating system asks for less motion we
 * honour it rather than second-guess it (SC 2.3.3 Animation from
 * Interactions). Durations are collapsed to a value small enough to be
 * imperceptible but non-zero, so any code awaiting a transitionend event
 * still receives one.
 */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
