/* Minimal styling for the Phase 1/2 smoke-test app, extended for Phase 3's
   diagnosis result card + charts (docs/design.md 9.4). Not the final brand
   look (docs/project-plan.md section 8: friendly/approachable, not a pro
   finance tool) -- just enough to make the flow legible.

   Colors are CSS custom properties (docs/design.md 9.4: "references/palette.
   mdのsurface/inkトークンをCSSカスタムプロパティとして定義し、
   prefers-color-schemeで自動切替"), so the chart SVGs never hardcode a fill/
   stroke -- they only reference a `--chart-*` variable via `class`. The
   :root block below is the light palette; the prefers-color-scheme: dark
   block only overrides the token values, not the rules that use them. */

:root {
  --surface-page: #faf7f1;
  --surface-card: #ffffff;
  --surface-card-border: #e5ddd0;
  --ink-primary: #221f2b;
  --ink-secondary: #57515f;
  --ink-muted: #8a8390;

  /* docs/design.md 18.2: new brand accent (violet), used for headings,
     buttons/tap-targets, card accents/borders -- never the chart marks
     themselves (those stay on the separate --chart-* tokens below,
     unchanged). */
  --brand: #7c3aed;
  --brand-strong: #6423d1;
  --brand-soft: #f3ecfd;
  --brand-border: #ddccfa;
  --on-brand: #ffffff;
  --card-shadow: 0 1px 2px rgba(45, 26, 82, 0.05), 0 10px 28px rgba(45, 26, 82, 0.08);

  --surface-privacy: #eef7f0;
  --border-privacy: #cfe8d6;
  --ink-privacy: #1f6b3a;

  --border-dropzone: #bbbbbb;
  --border-dropzone-active: #4a90d9;
  --surface-dropzone-active: #eef4fb;

  --surface-error: #fdecec;
  --border-error: #f3b7b7;

  /* docs/design.md 9.4's pinned chart colors (light mode) -- unchanged by
     the 18.2 brand-accent work above; the chart marks never use --brand*. */
  --chart-positive: #2a78d6;
  --chart-negative: #e34948;
  --chart-baseline: #f0efec;
  --chart-sequential: #2a78d6;
}

@media (prefers-color-scheme: dark) {
  :root {
    --surface-page: #141020;
    --surface-card: #1e1930;
    --surface-card-border: #362c4d;
    --ink-primary: #f1eef7;
    --ink-secondary: #cbc4d9;
    --ink-muted: #948da3;

    --brand: #a78bfa;
    --brand-strong: #c4b5fd;
    --brand-soft: #291f45;
    --brand-border: #453a68;
    --on-brand: #1c1330;
    --card-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), 0 10px 28px rgba(0, 0, 0, 0.4);

    --surface-privacy: #17251c;
    --border-privacy: #274a33;
    --ink-privacy: #8fd6a7;

    --border-dropzone: #4a4a4e;
    --border-dropzone-active: #3987e5;
    --surface-dropzone-active: #1c2733;

    --surface-error: #2e1f1f;
    --border-error: #6b3a3a;

    /* docs/design.md 9.4's pinned chart colors (dark mode) -- unchanged. */
    --chart-positive: #3987e5;
    --chart-negative: #e66767;
    --chart-baseline: #383835;
    --chart-sequential: #3987e5;
  }
}

body {
  margin: 0;
  /* docs/design.md 18.1: system fonts only, no external/bundled fonts. */
  font-family: -apple-system, BlinkMacSystemFont, "Hiragino Sans", "Noto Sans JP",
    "Yu Gothic", sans-serif;
  background: var(--surface-page);
  color: var(--ink-primary);
  line-height: 1.55;
}

.page {
  max-width: 34rem;
  margin: 0 auto;
  padding: 1.75rem 1.1rem 3.5rem;
}

/* -- Intro/landing hero (docs/design.md 18.3): replaces the old plain
   "動作確認版 (Phase 2)" heading with a real headline + tagline. -- */

.hero {
  text-align: center;
  padding-top: 0.25rem;
}

.hero h1 {
  margin: 0;
  font-size: 1.65rem;
  font-weight: 800;
  letter-spacing: -0.01em;
  color: var(--ink-primary);
}

.hero-tagline {
  margin: 0.55rem 0 0;
  font-size: 0.95rem;
  color: var(--ink-secondary);
}

/* -- Privacy note, restyled as a compact trust badge (18.3: "控えめな
   バッジ/カード風の見せ方") -- same full text, lighter visual weight. -- */

.privacy-pill {
  margin: 1.1rem auto 0;
  max-width: 28rem;
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  background: var(--surface-privacy);
  border: 1px solid var(--border-privacy);
  border-radius: 1rem;
  padding: 0.65rem 0.9rem;
  font-size: 0.76rem;
  line-height: 1.45;
  color: var(--ink-privacy);
  text-align: left;
}

.privacy-pill-icon {
  flex: none;
  width: 1.05rem;
  height: 1.05rem;
  margin-top: 0.15rem;
  color: var(--ink-privacy);
}

/* -- Dropzone: large, inviting, rounded call-to-action card (18.3), not
   just a dashed-border box. -- */

.dropzone {
  margin-top: 1.5rem;
  padding: 2.1rem 1.25rem;
  border: 2px dashed var(--brand-border);
  border-radius: 1.5rem;
  background: var(--surface-card);
  box-shadow: var(--card-shadow);
  text-align: center;
  color: var(--ink-secondary);
  transition: border-color 0.15s ease, background-color 0.15s ease, transform 0.15s ease;
}

.dropzone-active {
  border-color: var(--brand);
  background: var(--brand-soft);
  transform: scale(1.01);
}

.dropzone-icon {
  color: var(--brand);
}

.dropzone-title {
  margin: 0.5rem 0 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--ink-primary);
}

.dropzone-subtitle {
  margin: 0.4rem 0 1.15rem;
  font-size: 0.85rem;
  color: var(--ink-muted);
}

input[type="file"] {
  display: block;
  width: 100%;
  max-width: 22rem;
  margin: 0 auto;
  font-size: 0.85rem;
  color: var(--ink-secondary);
}

input[type="file"]::file-selector-button {
  margin-right: 0.7rem;
  padding: 0.7rem 1.1rem;
  border: none;
  border-radius: 0.65rem;
  background: var(--brand);
  color: var(--on-brand);
  font-weight: 600;
  font-size: 0.85rem;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

input[type="file"]::file-selector-button:hover {
  background: var(--brand-strong);
}

.results-stack {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
  margin-top: 1.5rem;
}

/* -- Loading states (18.3): a friendlier message + CSS-only animation,
   replacing the plain "読み込み中" text, shared by both the file-parse
   ("Reading") and the network fetch ("Fetching") stages. -- */

.loading-card {
  margin-top: 1.5rem;
  padding: 2rem 1.5rem;
  text-align: center;
  background: var(--surface-card);
  border: 1px solid var(--surface-card-border);
  border-radius: 1.25rem;
  box-shadow: var(--card-shadow);
}

.spinner {
  width: 2.25rem;
  height: 2.25rem;
  margin: 0 auto 0.9rem;
  border-radius: 50%;
  border: 3px solid var(--surface-card-border);
  border-top-color: var(--brand);
  animation: prism-spin 0.8s linear infinite;
}

@keyframes prism-spin {
  to {
    transform: rotate(360deg);
  }
}

.loading-message {
  margin: 0;
  font-weight: 600;
  color: var(--ink-primary);
}

.loading-submessage {
  margin: 0.35rem 0 0;
  font-size: 0.85rem;
  color: var(--ink-muted);
}

/* -- docs/design.md 39: determinate progress for the per-ticker fetch loop,
   shown once `AnalysisState::Fetching`'s `total` is known -- a many-ticker
   fetch otherwise leaves the spinner above as the only feedback for however
   long the whole loop takes. -- */

.fetch-progress {
  margin-top: 1rem;
}

.fetch-progress-track {
  height: 0.5rem;
  border-radius: 999px;
  background: var(--brand-soft);
  overflow: hidden;
}

.fetch-progress-fill {
  height: 100%;
  border-radius: 999px;
  background: var(--brand);
  transition: width 0.2s ease;
}

.fetch-progress-count {
  margin: 0.5rem 0 0;
  font-size: 0.8rem;
  color: var(--ink-muted);
  font-variant-numeric: tabular-nums;
}

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

.error {
  background: var(--surface-error);
  border: 1px solid var(--border-error);
  border-radius: 1rem;
  padding: 1.1rem 1.25rem;
  color: var(--ink-primary);
  box-shadow: var(--card-shadow);
}

.error-detail {
  font-family: monospace;
  font-size: 0.85rem;
}

.summary .file-name {
  font-weight: 600;
}

.stats {
  padding-left: 1.2rem;
}

.row-errors {
  margin-top: 1rem;
  font-size: 0.85rem;
  color: var(--ink-secondary);
}

.row-errors ul {
  padding-left: 1.2rem;
}

/* -- docs/design.md 18.3's "結果画面": every section is now its own
   visually separated card (rounded corners, padding, a subtle shadow/
   border), replacing the old flat vertical dump. `.analysis` itself is a
   plain flex spacer (not a card) so its card children (`.diagnosis`,
   `.sixteen-type`, `.tilt`, plus the leaf error/loading states above) read
   as a consistent rhythm of cards, one per section. -- */

.analysis {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.summary,
.tilt,
.diagnosis,
.risk-return,
.sixteen-type,
.type-badge {
  background: var(--surface-card);
  border: 1px solid var(--surface-card-border);
  border-radius: 1.25rem;
  padding: 1.25rem 1.25rem 1.4rem;
  box-shadow: var(--card-shadow);
}

.analysis h2 {
  font-size: 1.05rem;
  margin: 0 0 0.6rem;
  color: var(--ink-primary);
}

/* -- docs/design.md 22: エントリータイプ (`.sixteen-type`, unchanged) and
   the new 利益タイプ/損失タイプ (`.type-badge`) cards are the product's
   headline payoff, so they get real hero weight: an accent bar up top and
   extra breathing room, on top of the shared card look above. `.diagnosis`
   (the retitled "ファクター内訳" chart section, 22.4) keeps the same
   treatment since it's still visually anchoring the top of the page, even
   though it no longer carries a `.diagnosis-card` headline of its own. -- */

.diagnosis,
.sixteen-type,
.type-badge {
  position: relative;
  overflow: hidden;
  padding-top: 1.5rem;
}

.diagnosis::before,
.sixteen-type::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 6px;
  background: linear-gradient(90deg, var(--brand) 0%, var(--brand-strong) 100%);
}

/* 利益タイプ/損失タイプ get a positive/negative-tinted accent bar instead of
   the brand gradient -- the same --chart-positive/--chart-negative tokens
   the factor chart bars (9.4節) and headline color below use to encode
   sign, so "positive = this card's color" reads consistently with the
   chart right below it. */

.type-badge::before {
  content: "";
  position: absolute;
  inset: 0 0 auto 0;
  height: 6px;
}

.type-badge-profit::before {
  background: var(--chart-positive);
}

.type-badge-loss::before {
  background: var(--chart-negative);
}

.type-badge-profit .diagnosis-headline {
  color: var(--chart-positive);
}

.type-badge-loss .diagnosis-headline {
  color: var(--chart-negative);
}

/* docs/design.md 22.3's graceful fallback text (no positive/negative
   factor, or no Contribution-track data at all) -- same small/muted
   treatment the old `.light-shadow-empty` used for the equivalent "nothing
   to show on this side" case. */
.type-badge-empty {
  margin: 0.25rem 0 0;
  color: var(--ink-muted);
  font-size: 0.9rem;
  text-align: center;
}

.profit-loss-types {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* -- Example-result teaser (docs/design.md 44): sits right below the
   dropzone, always open (not a <details>) -- reuses `.sixteen-type`'s
   card/accent-bar look above so it reads as a real result card; the point
   is a first-time visitor sees the actual payoff (a persona card) with zero
   clicks, unlike the full 16-type list further down which stays collapsed.
   `.teaser-badge` is the one visual cue distinguishing it from a real
   result. -- */

.result-teaser {
  margin-top: 1.1rem;
}

.teaser-badge {
  display: inline-block;
  margin-bottom: 0.5rem;
  padding: 0.2rem 0.65rem;
  border-radius: 999px;
  background: var(--brand-soft);
  color: var(--brand-strong);
  font-size: 0.72rem;
  font-weight: 700;
}

.teaser-note {
  margin-top: 0.9rem;
  font-size: 0.78rem;
  text-align: center;
}

.diagnosis-card {
  margin-top: 0.25rem;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 0;
  text-align: center;
}

.diagnosis-headline {
  margin: 0;
  font-size: 1.75rem;
  font-weight: 800;
  color: var(--brand-strong);
}

.diagnosis-description {
  margin: 0.5rem 0 0;
  font-size: 1rem;
  color: var(--ink-secondary);
}

.diagnosis-track {
  margin: 0.75rem 0 0;
  font-size: 0.85rem;
  color: var(--ink-muted);
}

/* Section 21: X share button -- same brand-filled pill treatment as the
   dropzone's file-selector-button, since both are the "primary action"
   affordance of their respective card. */
.share-button-row {
  display: flex;
  justify-content: center;
  margin: 0.5rem 0 1rem;
}

.share-button {
  display: inline-block;
  padding: 0.7rem 1.4rem;
  border-radius: 0.65rem;
  background: var(--brand);
  color: var(--on-brand);
  font-weight: 600;
  font-size: 0.9rem;
  text-decoration: none;
  transition: background-color 0.15s ease;
}

.share-button:hover {
  background: var(--brand-strong);
}

.diagnosis-insufficient {
  text-align: center;
  color: var(--ink-secondary);
}

.diagnosis-insufficient p:first-of-type {
  font-weight: 700;
  color: var(--ink-primary);
}

/* -- Phase 3 charts (docs/design.md 9.4): plain, un-styled SVG containers;
   every color comes from the `--chart-*` tokens above via the classes
   below, applied to the SVG marks themselves. -- */

.chart-section {
  margin-top: 1.25rem;
}

.chart-section h3 {
  font-size: 0.95rem;
  margin-bottom: 0.5rem;
  color: var(--ink-primary);
}

.factor-chart,
.industry-chart {
  display: block;
  width: 100%;
  height: auto;
}

.chart-baseline {
  stroke: var(--chart-baseline);
  stroke-width: 2;
}

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

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

.chart-bar-sequential {
  fill: var(--chart-sequential);
}

/* -- docs/design.md section 41's risk-return scatter plot (`charts::
   render_scatter_chart`): risk on x, return on y. The "合計" point is
   bigger/brand-colored (this card's headline number, same `--brand`
   treatment as `.sixteen-code`); the 9 factor points are smaller and use
   `--chart-sequential` (the same single hue the industry chart uses for
   "independent magnitudes, not a diverging signed value"). Corner labels
   use `--chart-positive`/`--chart-negative` -- the same tokens the
   diverging factor chart already uses for "helped"/"hurt" -- so "favorable
   corner"/"unfavorable corner" reads consistently with the rest of the
   app's color language. -- */

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

.scatter-point-total {
  fill: var(--brand);
  stroke: var(--surface-card);
  stroke-width: 2;
}

.scatter-point-factor {
  fill: var(--chart-sequential);
  opacity: 0.85;
}

.scatter-label {
  font-size: 9px;
  fill: var(--ink-secondary);
}

.scatter-label-total {
  font-size: 11px;
  font-weight: 700;
  fill: var(--brand-strong);
}

.scatter-axis-label {
  font-size: 10px;
  fill: var(--ink-muted);
}

.scatter-corner-label {
  font-size: 9px;
}

.scatter-corner-good {
  fill: var(--chart-positive);
}

.scatter-corner-bad {
  fill: var(--chart-negative);
}

.chart-label {
  font-size: 11px;
  fill: var(--ink-secondary);
}

.chart-value {
  font-size: 11px;
  fill: var(--ink-primary);
  font-variant-numeric: tabular-nums;
}

/* -- docs/design.md section 11's one-line-per-factor explanations, shown
   right under the factor chart. Small/muted text, deliberately understated
   compared to `.diagnosis-headline`/`.diagnosis-description` above (that's
   the "why you got typed this way" headline; this is a plain glossary of
   "what does this factor measure", so it should read as reference material,
   not as more of the result). -- */

.factor-legend {
  margin: 0.75rem 0 0;
  display: grid;
  gap: 0.35rem;
}

.factor-legend-item {
  display: grid;
  grid-template-columns: 6.5rem 1fr;
  gap: 0.5rem;
  font-size: 0.8rem;
}

.factor-legend-item dt {
  font-weight: 600;
  color: var(--ink-secondary);
}

.factor-legend-item dd {
  margin: 0;
  color: var(--ink-muted);
}

/* -- docs/design.md section 16's "16タイプ" section (`diagnosis::
   render_sixteen_type`), reusing `.diagnosis-card`/`.diagnosis-headline`/
   `.diagnosis-description` above (also reused by the new `.type-badge`
   cards, docs/design.md 22) rather than a parallel set of styles. Only the
   4-character code (`.sixteen-code`) is new: it's this diagnosis's
   "shareable result" analog to a plain headline, so it gets even more
   weight than `.diagnosis-headline` -- larger, with letter-spacing to read
   as a deliberate short code rather than a run of
   Japanese prose. -- */

.sixteen-code {
  margin: 0;
  /* clamp() rather than a fixed 2.4rem: at a ~390px mobile viewport, 4
     characters at 2.4rem + 0.2em letter-spacing would overflow the card's
     content width (docs/design.md 18.3's mobile-first requirement). */
  font-size: clamp(1.85rem, 9vw, 2.4rem);
  font-weight: 800;
  letter-spacing: 0.15em;
  color: var(--brand);
  word-break: break-all;
}

.sixteen-axes {
  margin: 0.75rem 0 0;
  display: grid;
  gap: 0.5rem;
}

.sixteen-axis-item {
  display: grid;
  grid-template-columns: 6.5rem 1fr;
  gap: 0.5rem;
  font-size: 0.9rem;
  align-items: baseline;
}

.sixteen-axis-item dt {
  font-weight: 600;
  color: var(--ink-secondary);
}

.sixteen-axis-item dd {
  margin: 0;
  color: var(--ink-primary);
}

.sixteen-axis-item dd strong {
  color: var(--chart-positive);
}

/* -- docs/design.md 18.3: the more technical/diagnostic bits (per-month
   fetch status, row-error details) are demoted into a <details>/<summary>
   collapsible, available for transparency but not visually competing with
   the actual diagnosis content above. Uses the browser's own native
   disclosure marker (no icon font/emoji), only its color is themed. -- */

details.details-card {
  background: var(--surface-card);
  border: 1px solid var(--surface-card-border);
  border-radius: 1.1rem;
  padding: 0.95rem 1.1rem;
  box-shadow: var(--card-shadow);
}

details.details-card summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--ink-primary);
}

details.details-card summary::marker {
  color: var(--brand);
}

details.details-card[open] summary {
  margin-bottom: 0.75rem;
}

.details-inline {
  margin-top: 0.9rem;
  font-size: 0.85rem;
  color: var(--ink-secondary);
}

.details-inline summary {
  cursor: pointer;
  font-weight: 600;
}

.details-inline summary::marker {
  color: var(--brand);
}

.details-inline[open] summary {
  margin-bottom: 0.5rem;
}

/* -- The エントリータイプ 16-type reference table (docs/design.md
   `render_sixteen_type_reference_table`): a plain scrollable list rather
   than an HTML <table>, matching this app's existing dl-based layouts
   (.factor-legend/.sixteen-axes above) and avoiding a wide fixed-column
   table that would need horizontal scroll on a narrow viewport. -- */

.sixteen-type-reference {
  margin-top: 1.1rem;
}

.sixteen-type-reference-list {
  margin: 0;
  display: grid;
  gap: 0.65rem;
}

.sixteen-type-reference-item {
  padding-bottom: 0.65rem;
  border-bottom: 1px solid var(--surface-card-border);
}

.sixteen-type-reference-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.sixteen-type-reference-item dt {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-primary);
}

.sixteen-type-reference-code {
  font-weight: 800;
  letter-spacing: 0.08em;
  color: var(--brand);
}

.sixteen-type-reference-item dd {
  margin: 0.15rem 0 0;
  font-size: 0.8rem;
}

.sixteen-type-persona-detail {
  margin-top: 0.35rem;
  font-size: 0.8rem;
}

.sixteen-type-persona-detail summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--brand-strong);
}

.sixteen-type-persona-detail summary::marker {
  color: var(--brand);
}

.sixteen-type-persona-detail[open] summary {
  margin-bottom: 0.5rem;
}

/* -- MBTI-style detailed persona write-up (`diagnosis::
   render_persona_profile`, `persona::PersonaProfile`): shared between the
   user's own result card (shown inline, not collapsed -- it's the payoff of
   their own diagnosis) and each row of the 16-type reference table (nested
   inside `.sixteen-type-persona-detail` above, so browsing stays scannable
   until a row is expanded). -- */

.persona-profile {
  margin-top: 0.9rem;
  padding-top: 0.9rem;
  border-top: 1px solid var(--surface-card-border);
}

.persona-catchphrase {
  margin: 0;
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--brand-strong);
}

.persona-overview {
  margin: 0.4rem 0 0;
  font-size: 0.9rem;
  color: var(--ink-secondary);
}

.persona-traits {
  margin-top: 0.75rem;
  display: grid;
  gap: 0.75rem;
}

@media (min-width: 640px) {
  .persona-traits {
    grid-template-columns: 1fr 1fr;
  }
}

.persona-traits h4 {
  margin: 0 0 0.35rem;
  font-size: 0.8rem;
  color: var(--ink-primary);
}

.persona-traits ul {
  margin: 0;
  padding-left: 1.1rem;
  display: grid;
  gap: 0.3rem;
  font-size: 0.8rem;
  color: var(--ink-secondary);
}

.persona-fits {
  margin: 0.75rem 0 0;
  font-size: 0.8rem;
}

/* -- The "証券会社ごとのCSV取得方法" help section (main.rs's
   `render_csv_help`), right below the dropzone. Same dl-based list shape
   as .sixteen-type-reference-* above (name + description, divided rows,
   no HTML <table>), plus a link per row. -- */

.csv-help {
  margin-top: 1.1rem;
}

.csv-help-list {
  margin: 0;
  display: grid;
  gap: 0.65rem;
}

.csv-help-item {
  padding-bottom: 0.65rem;
  border-bottom: 1px solid var(--surface-card-border);
}

.csv-help-item:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.csv-help-item dt {
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink-primary);
}

.csv-help-item dd {
  margin: 0.15rem 0 0;
  font-size: 0.8rem;
  color: var(--ink-secondary);
}

.csv-help-item dd a {
  color: var(--brand);
  font-weight: 600;
}
