/* Styled after turpin.dev: Oswald for headings and figures, the system face
   for reading. Oswald is under the SIL Open Font Licence, fonts/OFL.txt. */
@font-face {
  font-family: "Oswald";
  src: url("/fonts/oswald.woff2") format("woff2");
  font-weight: 200 700;
  font-display: swap;
}

/* Colour roles, swapped whole for dark mode */
:root {
  --display: "Oswald", "Helvetica Neue Condensed", "Arial Narrow", system-ui, sans-serif;
  --mono: ui-monospace, "SF Mono", Menlo, monospace;
  color-scheme: light;
  --surface-0: #f4f3f0;
  --surface-1: #fcfcfb;
  --line: #e2e1dc;
  --ink: #0b0b0b;
  --ink-2: #52514e;
  --accent: #d95926;
  --pass: #2f9e5b;
  --fail: #d6402b;
  --idle: #a3a29b;
  --block: #121211;
  --block-ink: #f0efec;
  --block-ink-2: #c3c2b7;
  /* Chart line: validated for contrast and lightness on each surface */
  --chart-line: #d95926;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    --surface-0: #121211;
    --surface-1: #1a1a19;
    --line: #2e2e2b;
    --ink: #f0efec;
    --ink-2: #c3c2b7;
    --accent: #eb6834;
    --pass: #4cc47c;
    --fail: #f0654f;
    --idle: #6d6c66;
    --block: #b8461c;
    --block-ink: #fff;
    --block-ink-2: #fff;
    --chart-line: #e8622e;
  }
}
:root[data-theme="dark"] {
  --chart-line: #e8622e;
  color-scheme: dark;
  --surface-0: #121211;
  --surface-1: #1a1a19;
  --line: #2e2e2b;
  --ink: #f0efec;
  --ink-2: #c3c2b7;
  --accent: #eb6834;
  --pass: #4cc47c;
  --fail: #f0654f;
  --idle: #6d6c66;
  --block: #b8461c;
  --block-ink: #fff;
  --block-ink-2: #fff;
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--surface-0);
  color: var(--ink);
  font: 17px/1.55 system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
}
main { max-width: 1100px; margin: 0 auto; padding: 0 16px 40px; }
h1, h2, h3 { font-family: var(--display); font-weight: 500; }
a { color: var(--accent); }
.small { color: var(--ink-2); font-size: 14px; margin: 0; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; border-radius: 4px; }
.num { font-variant-numeric: tabular-nums; }

/* Opening: the name huge on the left, the live status board on the right */
.hero {
  display: grid; grid-template-columns: minmax(0, 6fr) minmax(0, 5fr); gap: 48px; align-items: center;
  max-width: 1100px; margin: 0 auto; padding: 64px 16px 56px;
}
.hero h1 {
  font-size: clamp(80px, 13vw, 168px); line-height: 0.86; margin: 22px 0 18px;
  font-weight: 600; letter-spacing: -0.015em; text-transform: uppercase;
}
/* The logo, TURP.trade with the meter for the full stop: bars on the baseline, sized to the letters */
.hero h1.logo { display: flex; align-items: flex-end; font-size: clamp(56px, 9.4vw, 112px); white-space: nowrap; }
.logo .tld { color: var(--accent); text-transform: lowercase; }
.logo .meter { height: 0.5em; gap: 0.035em; margin: 0 0.06em; }
.logo .meter i { width: 0.055em; border-radius: 0.02em; }
.tagline { font-family: var(--display); font-size: clamp(24px, 3vw, 32px); line-height: 1.15; margin: 0 0 14px; }
.lede { font-size: 19px; color: var(--ink-2); margin: 0; max-width: 500px; }

/* Level meter in the accent; it stills when the market is closed */
.meter { display: flex; align-items: flex-end; gap: 5px; height: 48px; }
.meter i {
  display: block; width: 9px; height: 100%; border-radius: 3px; background: var(--accent);
  transform-origin: bottom; animation: level 1.6s ease-in-out infinite alternate;
}
.meter i:nth-child(1) { animation-duration: 1.3s; transform: scaleY(0.45); }
.meter i:nth-child(2) { animation-duration: 0.9s; animation-delay: -0.4s; }
.meter i:nth-child(3) { animation-duration: 1.1s; animation-delay: -0.2s; }
.meter i:nth-child(4) { animation-duration: 0.8s; animation-delay: -0.6s; }
.meter i:nth-child(5) { animation-duration: 1.4s; animation-delay: -0.3s; }
.meter.closed i { animation: none; background: var(--idle); }
.meter.closed i:nth-child(odd) { transform: scaleY(0.35); }
.meter.closed i:nth-child(even) { transform: scaleY(0.2); }
@keyframes level {
  from { transform: scaleY(0.25); }
  to { transform: scaleY(1); }
}
@media (prefers-reduced-motion: reduce) {
  .meter i { animation: none; }
  .meter i:nth-child(odd) { transform: scaleY(0.6); }
}

.pill {
  display: inline-flex; flex-wrap: wrap; align-items: baseline; gap: 6px; margin: 20px 0 0; padding: 7px 16px;
  border-radius: 18px; background: var(--surface-1); border: 1px solid var(--line); color: var(--ink-2); font-size: 15px;
}
.pill span {
  font-family: var(--display); text-transform: uppercase; letter-spacing: 0.06em; font-size: 13px; color: var(--accent);
}

/* Status board, like a departures board */
.board {
  background: var(--surface-1); border: 1px solid var(--line); border-radius: 14px;
  padding: 20px 8px 8px; box-shadow: 0 24px 60px rgba(0, 0, 0, 0.12);
}
.board h2, .section-title {
  font-size: 15px; margin: 0 0 8px; padding: 0 14px;
  text-transform: uppercase; letter-spacing: 0.08em; color: var(--ink-2);
}
.board dl { margin: 0; }
.board dl > div {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: 4px 10px;
  padding: 9px 14px;
}
.board dl > div + div { border-top: 1px solid var(--line); }
.board dt { color: var(--ink-2); font-size: 15px; }
.board dd { margin: 0; font-family: var(--display); font-weight: 500; font-size: 24px; line-height: 1.15; text-align: right; }

@media (max-width: 860px) {
  .hero { grid-template-columns: minmax(0, 1fr); padding-top: 40px; gap: 36px; }
}

/* True figures, large */
.figures {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  margin: 0 0 56px; border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.figures div { padding: 22px 18px 20px 0; display: flex; flex-direction: column; gap: 4px; }
.figures b { font-family: var(--display); font-weight: 600; font-size: 56px; line-height: 1; color: var(--accent); }
.figures b.up { color: var(--pass); }
.figures b.down { color: var(--fail); }
.figures span { color: var(--ink-2); font-size: 15px; line-height: 1.35; max-width: 220px; }

.section-title { padding: 0; margin: 0 0 14px; }

/* Panels of rows with a status dot */
.columns { display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); gap: 14px; margin-bottom: 56px; }
.columns .panel { margin-bottom: 0; }
@media (max-width: 860px) { .columns { grid-template-columns: minmax(0, 1fr); } }

.panel {
  background: var(--surface-1); border: 1px solid var(--line); border-radius: 12px;
  padding: 22px 22px 10px; margin-bottom: 56px;
}
.panel-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 4px 16px; margin-bottom: 8px; }
.panel-head .section-title { margin: 0; }
.rows { list-style: none; margin: 0; padding: 0; }
.rows li {
  display: grid; grid-template-columns: 14px minmax(70px, 110px) minmax(0, 1fr) auto; align-items: baseline; gap: 4px 14px;
  padding: 12px 0; border-top: 1px solid var(--line);
}
.rows li.empty { display: block; color: var(--ink-2); }
.status { display: block; width: 10px; height: 10px; border-radius: 50%; background: var(--idle); align-self: center; }
.status.success { background: var(--pass); box-shadow: 0 0 0 4px color-mix(in srgb, var(--pass) 18%, transparent); }
.status.failure { background: var(--fail); box-shadow: 0 0 0 4px color-mix(in srgb, var(--fail) 18%, transparent); }
.status.open { background: var(--accent); box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent) 18%, transparent); }
.symbol { font-family: var(--display); font-size: 20px; font-weight: 500; color: var(--ink); }
.what { color: var(--ink-2); overflow-wrap: anywhere; }
.what code {
  font: 0.85em var(--mono); background: var(--surface-0); padding: 1px 5px; border-radius: 5px; color: var(--ink);
  white-space: nowrap;
}
/* Narrow panels: a fixed symbol column so names and strategies stay on one line */
.rows.compact li { grid-template-columns: 14px 56px minmax(0, 1fr) auto; }
.when { color: var(--ink-2); font: 13px var(--mono); white-space: nowrap; text-align: right; }
@media (max-width: 640px) {
  .rows li, .rows.compact li { grid-template-columns: 14px minmax(0, 1fr) auto; }
  .what { grid-column: 2 / -1; grid-row: 2; }
  .figures b { font-size: 44px; }
  .board dd { font-size: 20px; }
}

/* Dark block bookending the page */
.studio {
  display: grid; grid-template-columns: minmax(0, 2fr) minmax(0, 3fr); gap: 24px 40px;
  background: var(--block); color: var(--block-ink); border-radius: 12px; padding: 34px 38px;
}
.studio h2 { font-size: 40px; line-height: 1; margin: 0 0 10px; text-transform: uppercase; }
.studio p { margin: 0; color: var(--block-ink-2); }
.studio ul { list-style: none; margin: 0; padding: 0; color: var(--block-ink-2); }
.studio li { padding: 6px 0; border-top: 1px solid color-mix(in srgb, var(--block-ink) 18%, transparent); }
.studio li:first-child { border-top: 0; }
.studio b { color: var(--block-ink); font-weight: 600; }
@media (max-width: 760px) { .studio { grid-template-columns: 1fr; padding: 26px 22px; } }

footer { max-width: 1100px; margin: 0 auto; padding: 24px 16px 48px; color: var(--ink-2); font-size: 14px; }

/* Balance: account value over time, a single 2px line over a faint wash, a
   hairline at the starting balance, and a crosshair tooltip */
.balance .panel-head { margin-bottom: 4px; }
.ranges { display: flex; flex-wrap: wrap; gap: 4px; }
.ranges button {
  font: 13px var(--display); text-transform: uppercase; letter-spacing: 0.06em; cursor: pointer;
  color: var(--ink-2); background: transparent; border: 1px solid var(--line); border-radius: 999px; padding: 3px 12px;
}
.ranges button[aria-pressed="true"] { color: var(--ink); border-color: var(--ink-2); }
.balance-figure { margin: 4px 0 8px; display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 14px; }
.balance-figure b { font-family: var(--display); font-weight: 600; font-size: 44px; line-height: 1; }
.balance-figure span { color: var(--ink-2); font-size: 15px; }
.balance-figure span.up { color: var(--pass); }
.balance-figure span.down { color: var(--fail); }
.chart { position: relative; height: 220px; margin-bottom: 8px; touch-action: pan-y; }
/* While the balance loads (a couple of seconds, as it replays the trades into
   the indices), the old chart fades and a small spinner sits in the middle */
.chart.loading svg { opacity: 0.35; transition: opacity 0.2s; }
.chart.loading::after {
  content: ""; position: absolute; top: 50%; left: 50%; width: 28px; height: 28px; margin: -14px 0 0 -14px;
  border: 3px solid var(--line); border-top-color: var(--chart-line); border-radius: 50%;
  animation: spin 0.8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes pulse { 50% { opacity: 0.3; } }
@media (prefers-reduced-motion: reduce) {
  .chart.loading::after { animation: pulse 1.6s ease-in-out infinite; }
}
.chart svg { display: block; width: 100%; height: 100%; overflow: visible; }
.chart .grid { stroke: var(--line); stroke-width: 1; }
.chart .baseline { stroke: var(--ink-2); stroke-width: 1; opacity: 0.6; }
.chart .axis { fill: var(--ink-2); font: 12px system-ui, sans-serif; }
.chart .line { fill: none; stroke: var(--chart-line); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.chart .wash { fill: var(--chart-line); opacity: 0.1; }
/* Comparison lines: the same trades in an index, thinner and in neutral ink
   so the balance stays the one that reads first, told apart by dash pattern
   and named at their ends and in the legend */
.chart .other, .legend .other { fill: none; stroke: var(--ink-2); stroke-width: 1.5; stroke-linejoin: round; }
.chart .dashed, .legend .dashed { stroke-dasharray: 6 4; }
.chart .dotted, .legend .dotted { stroke-dasharray: 1.5 3; stroke-linecap: round; }
.chart .dashdot, .legend .dashdot { stroke-dasharray: 8 3 1.5 3; stroke-linecap: round; }
.legend .line { stroke: var(--chart-line); stroke-width: 2; }
.legend { display: flex; flex-wrap: wrap; gap: 4px 18px; margin: 8px 0 0; color: var(--ink-2); }
.legend > span { display: inline-flex; align-items: center; gap: 6px; }
.legend b { color: var(--ink); font-weight: 600; letter-spacing: 0.02em; }
.legend .own b, .chart .axis.own { fill: var(--chart-line); color: var(--chart-line); font-weight: 600; }
.tip .tip-other { display: block; color: var(--ink-2); }
.chart .cross { stroke: var(--ink-2); stroke-width: 1; }
.chart .dot { fill: var(--chart-line); stroke: var(--surface-1); stroke-width: 2; }
.chart .empty { fill: var(--ink-2); font: 15px system-ui, sans-serif; }
.tip {
  position: absolute; top: 0; pointer-events: none; background: var(--surface-1); border: 1px solid var(--line);
  border-radius: 8px; padding: 6px 10px; box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12); white-space: nowrap; font-size: 13px;
}
.tip b { display: block; font-size: 15px; color: var(--ink); }
.tip span { color: var(--ink-2); }
.table-view summary { cursor: pointer; color: var(--ink-2); font-size: 14px; margin-bottom: 8px; }
.table-view table { border-collapse: collapse; font-size: 14px; margin-bottom: 8px; }
.table-view th, .table-view td { text-align: left; padding: 4px 16px 4px 0; border-top: 1px solid var(--line); }
.table-view td:last-child { font-variant-numeric: tabular-nums; }

/* Open positions: one card per holding, each with its own small chart */
.positions { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); gap: 14px; margin-bottom: 12px; }
.position { border: 1px solid var(--line); border-radius: 10px; padding: 14px 14px 6px; min-width: 0; }
.position-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px; }
.position-head .symbol { font-size: 24px; }
.position-head code { font: 12px var(--mono); background: var(--surface-0); padding: 1px 5px; border-radius: 5px; }
.position-pl { font-family: var(--display); font-size: 20px; font-weight: 500; }
.position-pl.up { color: var(--pass); }
.position-pl.down { color: var(--fail); }
.position .small { margin: 2px 0 4px; }
.chart.small { height: 140px; margin-bottom: 0; }
.chart .mark { stroke: var(--ink-2); stroke-width: 1; opacity: 0.5; }
.chart .entry { stroke: var(--ink-2); stroke-width: 1; }
.chart .target { stroke: var(--pass); stroke-width: 1; }
.chart .stop { stroke: var(--fail); stroke-width: 1; }

/* Narrow panels: the figures go on a second line under the strategy, so
   long strategy names never run into them */
.rows.compact li { grid-template-columns: 14px 56px minmax(0, 1fr); }
.rows.compact .when { grid-column: 3; text-align: left; font-size: 12px; }

/* "realised" / "unrealised" beside a profit or loss: small, muted text so the
   figure's colour carries the result and the word says whether it's banked */
.pl-label {
  font: 12px system-ui, sans-serif; letter-spacing: 0; text-transform: none;
  color: var(--ink-2); font-weight: 400;
}

/* Text for screen readers only: off screen, but still read out, e.g. the
   balance chart's summary, which is its text alternative */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* A warning at the top of the board when the picks have gone stale: tinted
   with the status red, with an icon and a bold label so it isn't colour alone */
.alert {
  display: flex; gap: 10px; align-items: flex-start; margin: 0 0 12px; padding: 10px 12px;
  border-radius: 8px; border-left: 3px solid var(--fail); color: var(--ink); font-size: 14px; line-height: 1.4;
  background: color-mix(in srgb, var(--fail) 10%, var(--surface-1));
}
.alert[hidden] { display: none; }
.alert-icon { flex: none; width: 18px; height: 18px; margin-top: 1px; color: var(--fail); }
.board dd.warn { color: var(--fail); }

/* Strategies by day: scrolls sideways on narrow screens with the strategy
   column held in place; each cell is the day's result over its trade count */
.scorecard { overflow-x: auto; }
.scorecard table { border-collapse: collapse; font-size: 14px; min-width: 100%; }
.scorecard th, .scorecard td { text-align: left; padding: 8px 18px 8px 0; border-top: 1px solid var(--line); vertical-align: top; white-space: nowrap; }
.scorecard thead th { border-top: 0; color: var(--ink-2); font-weight: 500; font-size: 13px; }
.scorecard tbody th { position: sticky; left: 0; background: var(--surface-1); font-weight: 400; }
.scorecard .pl { display: block; font-weight: 600; }
.scorecard .pl.up { color: var(--pass); }
.scorecard .pl.down { color: var(--fail); }
.scorecard .count, .scorecard .nil { display: block; color: var(--ink-2); font-size: 12px; }
.scorecard tr.all th, .scorecard tr.all td { border-top: 2px solid var(--line); font-weight: 600; }

/* Recoveries the trader made by itself today: a calmer notice than the
   warning, in the accent orange, as it's information rather than a fault */
.notice {
  display: flex; gap: 10px; align-items: flex-start; margin: 0 0 12px; padding: 10px 12px;
  border-radius: 8px; border-left: 3px solid var(--accent); color: var(--ink); font-size: 14px; line-height: 1.4;
  background: color-mix(in srgb, var(--accent) 10%, var(--surface-1));
}
.notice[hidden] { display: none; }
.notice .alert-icon { color: var(--accent); }
.notice ul { margin: 2px 0 0; padding-left: 18px; }

/* Backtest profile page (profile.html): phase timings and hot-spot tables
   with a thin share bar under each figure, and the flame graph, which is a
   fixed-width SVG, scrolling sideways on narrow screens */
.profile { padding-top: 24px; }
.profile h1 { font-size: 56px; line-height: 1; margin: 8px 0 12px; text-transform: uppercase; }
.profile .lede { max-width: 70ch; margin: 0 0 8px; }
.profile #run { margin-bottom: 32px; }
.profile pre { overflow-x: auto; background: var(--surface-0); border-radius: 8px; padding: 12px; font-size: 13px; }
.profile code { font-family: var(--mono); font-size: 0.9em; }
.share {
  display: block; height: 4px; margin-top: 3px; border-radius: 2px; min-width: 1px;
  width: var(--w); background: var(--chart-line);
}
.bar-row { padding: 8px 0 12px; border-top: 1px solid var(--line); }
.bar-row:first-child { border-top: 0; }
.bar-row .share { height: 8px; }
.profile .scorecard td { min-width: 100px; }
.findings { margin: 0 0 14px; padding-left: 20px; max-width: 80ch; }
.findings li { margin-bottom: 10px; }
.flame { overflow-x: auto; margin-bottom: 14px; }
.flame object { display: block; width: 1200px; max-width: none; background: #fff; border-radius: 8px; }
/* The front page's profile summary: function names, each with its share */
.hot { list-style: none; margin: 8px 0 14px; padding: 0; font-size: 14px; }
.hot li { display: flex; justify-content: space-between; gap: 16px; padding: 6px 0; border-top: 1px solid var(--line); overflow-wrap: anywhere; }
.hot li:first-child { border-top: 0; }

/* The menu across the top of every page: the logo shrunk to a home link on
   the left (left out on the front page, where the full logo is right below),
   the pages on the right, the current one underlined in the accent */
.nav {
  display: flex; align-items: center; gap: 4px 18px; flex-wrap: wrap;
  max-width: 1100px; margin: 0 auto; padding: 18px 16px 0; font-size: 15px;
}
.nav .home {
  display: flex; align-items: flex-end; gap: 8px; margin-right: auto; color: var(--ink); text-decoration: none;
  font-family: var(--display); font-size: 28px; font-weight: 600; line-height: 0.86; text-transform: uppercase;
}
.nav .links { display: flex; gap: 16px; margin-left: auto; }
.nav .links a { color: var(--ink-2); text-decoration: none; }
.nav .links a:hover { color: var(--ink); }
.nav .links a[aria-current="page"] { color: var(--ink); box-shadow: inset 0 -2px 0 var(--accent); }
/* The level meter at the home link's size, still */
.meter.mini { height: 22px; gap: 2px; }
.meter.mini i { width: 4px; border-radius: 2px; animation: none; }
.meter.mini i:nth-child(1) { transform: scaleY(0.45); }
.meter.mini i:nth-child(2) { transform: scaleY(0.8); }
.meter.mini i:nth-child(3) { transform: scaleY(0.6); }
.meter.mini i:nth-child(4) { transform: scaleY(1); }
.meter.mini i:nth-child(5) { transform: scaleY(0.7); }
.hero { padding-top: 32px; }
