:root {
  --ink:#14201c; --muted:#5d6964; --paper:#f7f9f6; --surface:#fff; --panel:#edf2ed;
  --line:#d5ddd7; --green:#0f5c46; --green-2:#d9ebe3; --gold:#b08b3e; --red:#9b493f;
  --max:70rem; --font:Pretendard,"Apple SD Gothic Neo","Noto Sans KR","Malgun Gothic",system-ui,sans-serif;
  --font-num:Pretendard,"Apple SD Gothic Neo","Noto Sans KR","Malgun Gothic",system-ui,sans-serif;
  --font-tech:"Roboto Mono",SFMono-Regular,Consolas,monospace;
  --num:var(--font-num);
}
*{box-sizing:border-box} html{color-scheme:light} body{margin:0;background:var(--paper);color:var(--ink);font:400 1rem/1.55 var(--font);overflow-wrap:anywhere}
a{color:inherit;text-underline-offset:.2em} a:focus-visible,button:focus-visible,summary:focus-visible{outline:3px solid var(--gold);outline-offset:3px}
.neo-global-header__inner,.site-footer__inner,main{width:min(calc(100% - 2rem),var(--max));margin-inline:auto}
/* Base layout for the ONE canonical header component (global_navigation.py)
   -- these selectors were missing entirely from v3's first commit: the
   markup was renamed from .site-header/.wordmark/.global-nav to
   .neo-global-header/.neo-global-brand/.neo-global-nav, but the matching
   CSS was never written, so every route's header rendered with zero
   layout (default block stacking) even though the old, now-unreferenced
   .site-header rules still sat in this file looking like "real" CSS. */
.neo-global-header{border-bottom:1px solid var(--line);background:rgba(247,249,246,.98)}
.neo-global-header__inner{display:flex;align-items:center;justify-content:space-between;gap:1.5rem;min-height:4rem}
/* MOBILE HOME COLOR/READABILITY PASS (20260910), header audit: without
   min-width:0 a flex item's default min-width:auto lets it keep its
   full intrinsic content width even inside an overflow-x:auto box --
   the classic flexbox overflow bug. This let the nav's real content
   width (~462px) push past the viewport at 360px specifically (390px+
   had just enough room for the existing <430px gap/font-size shrink to
   compensate, 360px did not) -- confirmed by measuring every element's
   bounding box at 360px before this fix, not assumed. min-width:0 is
   the root-cause fix: the nav now truly scrolls horizontally within
   its own box exactly as overflow-x:auto already intended, instead of
   growing the page itself. Nav item count/links are unchanged. */
.neo-global-nav{display:flex;align-items:center;gap:.25rem 1.2rem;overflow-x:auto;white-space:nowrap;min-width:0}
.neo-global-nav a{display:inline-flex;align-items:center;min-height:44px;color:var(--muted);font-size:.875rem;font-weight:700;text-decoration:none}
main{min-height:70vh;padding-bottom:3rem}.section-label,.kicker,.tournament-context__eyebrow{margin:0;color:var(--green);font-size:.75rem;font-weight:850;letter-spacing:.11em;text-transform:uppercase}
.product-hero{display:grid;grid-template-columns:minmax(0,2.2fr) minmax(13rem,.8fr);gap:1.5rem;align-items:end;padding:clamp(1.25rem,3vw,2rem) 0 1.5rem;border-bottom:1px solid var(--line)}
.product-hero h1,.page-head h1{max-width:22ch;margin:.35rem 0 .6rem;font-size:clamp(1.75rem,2.6vw,2.4rem);line-height:1.18;letter-spacing:-.03em}.product-hero p,.page-head p{max-width:43rem;color:var(--muted)}
.hero-data{padding:1.4rem;border-top:4px solid var(--green);background:var(--surface)}.hero-data span,.hero-data p{display:block;margin:0;color:var(--muted);font-size:.82rem}.hero-data strong{display:block;font:800 3.5rem/1 var(--num);color:var(--green)}
.actions{display:flex;flex-wrap:wrap;gap:.6rem;margin-top:1.5rem}.primary-action,.secondary-action{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:.55rem .9rem;font-weight:750;text-decoration:none}.primary-action{background:var(--green);color:#fff}.secondary-action{border:1px solid var(--line);background:var(--surface);color:var(--green)}
.product-section{padding:2.25rem 0;border-bottom:1px solid var(--line);min-width:0}.section-heading{display:flex;align-items:end;justify-content:space-between;gap:1rem;margin-bottom:1.1rem}.section-heading h2,.product-section>h2,.stage-head h2,.tournament-summary h2{margin:.25rem 0;font-size:clamp(1.45rem,3vw,2rem);line-height:1.25;letter-spacing:-.025em}.state-chip,.label-chip{display:inline-flex;align-items:center;min-height:28px;padding:.2rem .55rem;background:var(--green-2);color:var(--green);font-size:.72rem;font-weight:800}
.latest-grid{display:grid;grid-template-columns:1fr 1fr auto;border:1px solid var(--line);background:var(--surface)}.latest-grid>div,.latest-grid>a{display:flex;flex-direction:column;justify-content:center;min-height:7.5rem;padding:1rem 1.25rem;border-right:1px solid var(--line)}.latest-grid>a{align-items:center;border:0;background:var(--panel);color:var(--green);font-weight:750}.latest-grid span,.latest-grid small{color:var(--muted)}.latest-grid strong{font-size:1.5rem}.latest-grid>div:nth-child(2) strong{font:800 1.8rem/1.2 var(--num);color:var(--green)}
.watch-grid{display:grid;grid-template-columns:repeat(4,1fr);border:1px solid var(--line);background:var(--surface)}.watch-grid article{position:relative;min-width:0;padding:1rem;border-right:1px solid var(--line)}.watch-grid article:last-child{border:0}.watch-grid article>span{position:absolute;right:.7rem;top:.5rem;color:var(--line);font:700 2rem/1 var(--num)}.watch-grid h3{margin:0 0 .35rem;font-size:1rem}.watch-grid strong{font:800 1.4rem/1 var(--num);color:var(--green)}
.movement-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:.75rem;margin-top:.75rem}.movement-grid article{display:grid;gap:.2rem;padding:1rem;background:var(--panel)}.movement-grid span{color:var(--muted);font-size:.8rem}.movement-grid b{font-family:var(--num);color:var(--green)}
.deep-question{display:grid;grid-template-columns:1.2fr 1.8fr auto;gap:1.5rem;align-items:center}.deep-question h2{margin:0}.compare-strip{display:grid;grid-template-columns:repeat(2,1fr);gap:.35rem}.compare-strip span{display:flex;justify-content:space-between;padding:.45rem .65rem;background:var(--surface);font-size:.84rem}.compare-strip b{font-family:var(--num);color:var(--green)}
.page-head{padding:3rem 0 2rem;border-bottom:1px solid var(--line)}.page-head.compact{padding-bottom:1.5rem}.tournament-row{display:grid;grid-template-columns:1fr auto;align-items:center;gap:2rem;padding:1.25rem;border:1px solid var(--line);background:var(--surface);text-decoration:none}.tournament-row h2{margin:.5rem 0 .2rem}.tournament-row>div:last-child{display:grid;text-align:right}.tournament-row strong{font-size:1.3rem}.tournament-row small{font-family:var(--num)}
.archive-card{padding:1.25rem;border:1px solid var(--line);background:var(--surface)}.archive-card h2{margin-top:0}.stage-links{display:flex;flex-wrap:wrap;gap:.4rem}.stage-links a{display:inline-flex;align-items:center;min-height:44px;padding:.4rem .8rem;border:1px solid var(--line);font-weight:750;text-decoration:none}
.tournament-context{padding-top:1.1rem;border-bottom:1px solid var(--line)}.tournament-context h1{margin:.2rem 0;font-size:clamp(1.6rem,2.6vw,2.3rem);line-height:1.2;letter-spacing:-.03em}.tournament-context h1 a{text-decoration:none}.tournament-context__meta{margin:.4rem 0 1rem;color:var(--muted);font-size:.82rem}.stage-nav{width:100%;overflow-x:auto;overscroll-behavior-inline:contain;-webkit-overflow-scrolling:touch}.stage-nav__list{display:flex;width:max-content;min-width:100%;margin:0;padding:0;list-style:none;white-space:nowrap}.stage-nav__item{flex:1 0 auto}.stage-nav__link,.stage-nav__disabled{display:inline-flex;align-items:center;justify-content:center;min-width:6rem;min-height:44px;padding:.55rem .85rem;font-size:.82rem;font-weight:800;text-decoration:none}.stage-nav__link{color:var(--muted)}.stage-nav__link[aria-current=page],.stage-nav__disabled[aria-current=page]{background:var(--green);color:#fff}.stage-nav__disabled{color:#919b96;cursor:not-allowed}
.tournament-summary{display:grid;grid-template-columns:1fr 2fr;gap:2rem;padding:2rem 0;border-bottom:1px solid var(--line)}.tournament-summary dl{display:grid;grid-template-columns:repeat(2,1fr);gap:.5rem;margin:0}.tournament-summary dl div{padding:.75rem;background:var(--surface)}.tournament-summary dt{color:var(--muted);font-size:.75rem}.tournament-summary dd{margin:.15rem 0 0;font-weight:700}
.outcome-grid{display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:1.25rem;margin-top:1rem}.outcome-grid>div:not(.outcome-arrow){padding:1.3rem;border:1px solid var(--line);background:var(--surface)}.outcome-grid span{color:var(--muted);font-size:.78rem}.outcome-grid h2{margin:.3rem 0}.outcome-grid strong{font:800 2rem/1.1 var(--num);color:var(--green)}.outcome-grid a{display:inline-flex;align-items:center;min-height:44px;color:var(--green);font-weight:750}.outcome-arrow{font-size:2rem;color:var(--gold)}.note{color:var(--muted);font-size:.85rem}
.timeline{display:grid;grid-template-columns:repeat(5,1fr);overflow-x:auto}.timeline a{display:grid;min-width:8rem;min-height:68px;padding:.7rem;border-top:3px solid var(--green);border-bottom:1px solid var(--line);text-decoration:none}.timeline span{color:var(--muted);font-size:.75rem}
.stage-head{padding:1.5rem 0 1.1rem;border-bottom:1px solid var(--line)}.stage-head p:last-child{max-width:50rem;color:var(--muted)}.result-head{border-top:4px solid var(--green)}
.table-scroll{width:100%;max-width:100%;overflow-x:auto;overscroll-behavior-inline:contain;-webkit-overflow-scrolling:touch}.data-table{width:100%;min-width:42rem;border-collapse:collapse;background:var(--surface);font-size:.875rem}.data-table th,.data-table td{padding:.62rem .7rem;border-bottom:1px solid var(--line);text-align:right;white-space:nowrap}.data-table th{background:var(--panel);color:var(--muted);font-size:.75rem}.data-table th:nth-child(2),.data-table td:nth-child(2){text-align:left}.data-table td:not(:nth-child(2)){font-family:var(--num);font-variant-numeric:tabular-nums}.data-table tbody tr:hover{background:#f1f5f1}.forecast-tools{display:flex;flex-wrap:wrap;gap:.35rem}.forecast-tools button{min-height:44px;padding:.45rem .75rem;border:1px solid var(--line);background:var(--surface);font:700 .8rem var(--font);cursor:pointer}.forecast-tools button[aria-pressed=true]{background:var(--green);color:#fff;border-color:var(--green)}
.charts-grid{display:grid;gap:1rem}.chart-card{min-width:0;padding:1.25rem;border:1px solid var(--line);background:var(--surface)}.chart-card header{display:flex;align-items:end;justify-content:space-between}.chart-card h3{margin:0;font-size:1.125rem;font-weight:700}.chart-scroll,.chart-full{width:100%;max-width:100%;overflow:visible}.line-chart,.bar-chart{display:block;width:100%;max-width:100%;min-width:0;height:auto}.chart-axis{stroke:#718078;stroke-width:1.2}.chart-grid{stroke:#e1e7e2;stroke-width:1}.chart-line{fill:none;stroke:var(--green);stroke-width:3;stroke-linejoin:round;stroke-linecap:round}.chart-point{fill:var(--surface);stroke:var(--green);stroke-width:3}.chart-x-label,.chart-y-label,.chart-value,.chart-missing,.chart-legend,.bar-label,.bar-number{font-family:var(--font);font-size:13px;font-weight:600;fill:var(--muted)}.chart-x-label,.chart-value,.chart-missing{text-anchor:middle}.chart-y-label,.bar-label{text-anchor:end}.chart-value{font-size:16px;fill:var(--green);font-weight:800}.chart-legend{font-size:14px;font-weight:700}.bar-value{fill:var(--green)}.bar-number{font-size:15px;font-weight:700}.trend-summary{margin:1.25rem 0 .6rem;font:700 clamp(1rem,2.5vw,1.25rem)/1.5 var(--num);color:var(--green)}.final-trends .chart-card{margin-bottom:1.5rem}.sg-summary{display:flex;gap:1rem;margin:1rem 0;font:700 1.1rem var(--num)}.composition-grid{display:grid;grid-template-columns:repeat(6,1fr);border:1px solid var(--line)}.composition-grid div{display:grid;padding:1rem;border-right:1px solid var(--line)}.composition-grid span{font-size:.78rem;color:var(--muted)}.composition-grid strong{font:800 1.5rem var(--num);color:var(--green)}.sr-data{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}
.comparison-table{display:grid;grid-template-columns:repeat(4,1fr);margin-top:1rem;border:1px solid var(--line);background:var(--surface)}.comparison-table>div{display:grid;gap:.3rem;padding:1rem;border-right:1px solid var(--line)}.comparison-table>div:last-child{border:0}.comparison-table span{color:var(--muted);font-size:.78rem}.comparison-table strong{font:800 1.35rem var(--num);color:var(--green)}
.result-card{display:grid;grid-template-columns:1fr 1.6fr;gap:1.5rem;padding:1.5rem;background:var(--green);color:#fff}.result-name{margin:.6rem 0 0;font-size:2rem;font-weight:800}.result-card p{margin-bottom:0}.result-score{margin:0!important;font:800 2.6rem/1 var(--num)}.result-score small{font-size:1rem}.round-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:.4rem;margin-top:1rem}.round-grid span{display:grid;padding:.45rem;border:1px solid rgba(255,255,255,.35);text-align:center}.round-grid small{font-size:.68rem}.round-grid strong{font-family:var(--num)}
.deep-link{display:flex;align-items:center;justify-content:space-between;gap:1rem;background:var(--panel);padding-inline:1.25rem}.unavailable{color:var(--muted)}.unavailable h2{color:var(--ink)}.evidence-section{color:var(--muted)}.evidence-detail summary{display:flex;align-items:center;min-height:44px;color:var(--green);font-weight:750;cursor:pointer}.evidence-detail dl{display:grid;grid-template-columns:10rem 1fr;gap:.35rem .8rem;font-size:.8rem}.evidence-detail dt{font-weight:700}.evidence-detail dd{margin:0}.evidence-detail code{font-family:var(--num);font-size:.7rem;overflow-wrap:anywhere}
.chart-takeaway{margin:.4rem 0 1.8rem;padding-left:.8rem;border-left:3px solid var(--gold);font-size:1rem;font-weight:650}.chart-feature{padding:1rem 0}.chart-feature h3{margin:.2rem 0;font-size:1.2rem;font-weight:750}.chart-subhead{margin:.2rem 0 .7rem;color:var(--muted);font-size:1rem}.chart-insight{margin:.6rem 0;padding:.75rem 1rem;background:var(--green-2);font-size:.95rem;font-weight:650}.chart-end-label{font-size:14px;font-weight:750;fill:var(--ink)}.chart-label-leader{fill:none;stroke-width:1.5;stroke-dasharray:3 3}.methodology-note{font-size:.8rem}.sg-explainer{max-width:48rem;padding:1rem;background:var(--green-2)}.sg-meanings{display:grid;grid-template-columns:repeat(2,1fr);gap:.6rem}.sg-meanings article{display:grid;gap:.2rem;padding:1rem;background:var(--surface);border:1px solid var(--line)}.sg-meanings b{font-size:1.05rem}.sg-meanings span{font-size:.9rem}.sg-meanings small{color:var(--muted)}.competitor-grid{display:grid;grid-template-columns:repeat(7,1fr);border:1px solid var(--line)}.competitor-grid article{display:grid;padding:.75rem;border-right:1px solid var(--line)}.competitor-grid span,.competitor-grid small{font-size:.75rem;color:var(--muted)}.competitor-grid strong{font:800 1.35rem var(--num);color:var(--green)}.probability-explainer{background:var(--panel);padding-inline:1.25rem}.monitor-grid{display:grid;grid-template-columns:repeat(4,1fr);margin-top:1rem}.monitor-grid span{display:grid;padding:1rem;border-top:3px solid var(--green);background:var(--surface)}.monitor-grid small{color:var(--muted)}
.principles{display:grid;grid-template-columns:repeat(3,1fr);border-bottom:1px solid var(--line)}.principles article{padding:1.5rem;border-right:1px solid var(--line)}.principles article:last-child{border:0}.principles b{color:var(--green);font-family:var(--num)}.principles h2{font-size:1.2rem}.principles p{color:var(--muted)}
.fixture-notice{margin:1rem 0;padding:.7rem;border:1px solid var(--gold);background:#fff8dc}.fixture-notice strong{margin-right:.7rem}.page-intro,.stage-placeholder{padding:2rem 0}.page-intro h1{font-size:2rem}
.site-footer{border-top:1px solid var(--line);background:var(--panel);color:var(--muted);font-size:.82rem}.site-footer__inner{padding:1.5rem 0}.site-footer nav{display:flex;flex-wrap:wrap;gap:.3rem 1rem}.site-footer nav a{display:inline-flex;align-items:center;min-height:44px}
@media(max-width:760px){.product-hero{grid-template-columns:1fr}.hero-data{display:grid;grid-template-columns:1fr auto;align-items:end}.hero-data p{grid-column:1/-1}.latest-grid{grid-template-columns:1fr 1fr}.latest-grid>a{grid-column:1/-1;min-height:44px}.watch-grid{grid-template-columns:repeat(2,1fr)}.watch-grid article:nth-child(2){border-right:0}.watch-grid article:nth-child(-n+2){border-bottom:1px solid var(--line)}.movement-grid{grid-template-columns:1fr}.deep-question{grid-template-columns:1fr}.tournament-summary{grid-template-columns:1fr}.outcome-grid{grid-template-columns:1fr}.outcome-arrow{transform:rotate(90deg)}.comparison-table{grid-template-columns:repeat(2,1fr)}.comparison-table>div:nth-child(2){border-right:0}.comparison-table>div:nth-child(-n+2){border-bottom:1px solid var(--line)}.result-card{grid-template-columns:1fr}.principles{grid-template-columns:1fr}.principles article{border-right:0;border-bottom:1px solid var(--line)}.deep-link{align-items:flex-start;flex-direction:column}.evidence-detail dl{grid-template-columns:1fr;gap:.1rem}.evidence-detail dd{margin-bottom:.6rem}.competitor-grid{grid-template-columns:repeat(2,1fr)}.monitor-grid{grid-template-columns:repeat(2,1fr)}.sg-meanings{grid-template-columns:1fr}}
@media(max-width:430px){.neo-global-header__inner,.site-footer__inner,main{width:min(calc(100% - 1.25rem),var(--max))}.neo-global-header__inner{gap:.6rem;min-height:3.5rem}.neo-global-nav{gap:.2rem .7rem;-webkit-mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent 100%);mask-image:linear-gradient(to right,#000 calc(100% - 28px),transparent 100%)}.neo-global-nav a{font-size:.8rem}.product-hero h1,.page-head h1{font-size:2rem}.tournament-summary dl{grid-template-columns:1fr}.watch-grid{grid-template-columns:1fr}.watch-grid article{border-right:0;border-bottom:1px solid var(--line)!important}.comparison-table{grid-template-columns:1fr}.comparison-table>div{border-right:0;border-bottom:1px solid var(--line)}.round-grid{grid-template-columns:repeat(2,1fr)}.section-heading{align-items:flex-start;flex-direction:column}.composition-grid{grid-template-columns:repeat(2,1fr)}.chart-card{padding:.65rem}.chart-x-label,.chart-y-label{font-size:12px}.chart-value{font-size:15px}}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important}}
.neo-global-brand{flex-wrap:wrap}.home-table th:nth-child(1),.home-table td:nth-child(1){text-align:center}.home-head{padding:1.5rem 0 1rem}.home-head h1{margin:.3rem 0 .55rem;font-size:clamp(1.7rem,3.5vw,2.35rem)}.home-head p{margin:.35rem 0}.home-summary{margin-top:.8rem}.page-head{padding:1.75rem 0 1.25rem}.product-section{padding:1.5rem 0}.ranking-help{margin-bottom:1rem}.home-table th,.home-table td{height:50px}
.mobile-navigation-contract{overflow-x: auto;white-space: nowrap;min-height: 44px}
.evidence-detail code{font-family:var(--font-tech)}
.result-score,.hero-data strong,.latest-grid strong,.watch-grid strong,.comparison-table strong,.data-table td,.round-grid strong,.chart-value,.chart-end-label,.bar-number{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
.home-summary{display:grid;grid-template-columns:auto 1fr auto 1fr;gap:.3rem 1rem;align-items:baseline;max-width:34rem;margin-top:1.5rem}.home-summary strong{color:var(--green);font:800 2rem/1 var(--num)}.home-summary span{color:var(--muted);font-size:.85rem}.home-tools{display:flex;align-items:center;flex-wrap:wrap;gap:.5rem;margin-bottom:1rem}.home-tools label{font-size:.8rem;font-weight:750}.home-tools input,.home-tools select{min-height:44px;padding:.55rem .7rem;border:1px solid var(--line);background:var(--surface);font:inherit}.home-tools input{min-width:min(18rem,100%)}.home-tools output{margin-left:auto;color:var(--muted);font-weight:750}.home-table th:nth-child(1),.home-table td:nth-child(1){text-align:left}.pending,.validation-state{color:var(--muted);font-family:var(--font);font-size:.78rem}.home-table small{font-size:.7rem;color:var(--muted)}
.ranking-help{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;margin:0 0 1.5rem;background:var(--line);border:1px solid var(--line)}.ranking-help div{padding:1rem;background:var(--surface)}.ranking-help dt{font-weight:800}.ranking-help dd{margin:.35rem 0 0;color:var(--muted);font-size:.85rem}.home-table{width:100%;min-width:960px;table-layout:fixed}.home-table th,.home-table td{height:52px;padding:.7rem .6rem;text-align:center;vertical-align:middle;font-variant-numeric:tabular-nums}.home-table th:nth-child(1),.home-table td:nth-child(1){width:12rem;text-align:left;white-space:normal;overflow-wrap:anywhere}.home-table th:nth-child(2),.home-table td:nth-child(2){width:9rem;text-align:center}.home-table th:nth-child(n+3),.home-table td:nth-child(n+3){text-align:center}.home-table th:last-child,.home-table td:last-child{width:12rem}.table-scroll{max-width:100%;overflow-x:auto}.table-scroll:focus-visible{outline:3px solid var(--green);outline-offset:2px}@media(max-width:760px){.ranking-help{grid-template-columns:repeat(2,1fr)}.home-table{min-width:880px}.home-table th,.home-table td{height:48px;padding:.6rem .5rem}.home-table th:nth-child(1),.home-table td:nth-child(1){width:10rem}}
@media(max-width:430px){.ranking-help{grid-template-columns:1fr}.home-tools output{width:100%;margin-left:0}.home-table{min-width:840px}}
/* MOBILE HOME COLOR/READABILITY PASS (20260910): column color system.
   Color marks data MEANING, not decoration --
     .metric-sg   = a value NEO itself computed from the corrected SG
                     warehouse (최근10R/최근5R SG) -- a very light green
                     tint, never a loud fill, numbers stay fully legible.
     .k-rank-cell = the official KLPGA rank -- neutral/cooler tint,
                     deliberately a lower visual priority than NEO's own
                     computed values.
     .metric-pos/.metric-neg = sign-only text color on genuine signed SG
                     averages (recent_10_sg/recent_5_sg/long_term_sg) --
                     positive (strokes gained) = green, negative = red.
                     Never applied to volatility (a non-negative
                     magnitude, not a gained/lost value) or to 현재
                     스코어 (to-par follows the opposite golf convention
                     and already has its own display treatment).
     .metric-empty = the "—" missing-data mark -- neutral muted gray,
                     never colored as if it were a real reading. */
.home-table td.metric-sg{background:#eff8f4}
.home-table td.k-rank-cell{background:#eef1f4;font-weight:800}
.home-table td.metric-pos{color:var(--green);font-weight:700}
.home-table td.metric-neg{color:var(--red);font-weight:700}
.home-table td.metric-empty{color:var(--muted)}
.home-table td.metric-secondary.metric-pos,.home-table td.metric-secondary.metric-neg{font-weight:600}
/* MOBILE HOME REBUILD: below 760px the table becomes one player = one
   compact row -- CSS Grid on tbody tr with named cell placement (same
   technique already proven on the KB tournament pages' mobile
   leaderboard), NOT a smaller version of the desktop table. thead is
   moved off-screen exactly like the existing OK Open mobile-card
   pattern; no markup change was needed, top120.js's search/sort only
   ever reads tr[data-player-row]'s data-* attributes and re-appends
   whole <tr> nodes, so it is unaffected by how each row's cells are
   laid out visually. The forced 840-880px min-width above (the actual
   root cause of the mobile horizontal-scroll defect) is overridden
   here so the table can finally shrink to the real viewport. */
@media(max-width:760px){
  .table-scroll{overflow-x:visible}
  .home-table{min-width:0;width:100%;table-layout:auto}
  .home-table,.home-table thead,.home-table tbody{display:block;width:100%}
  .home-table thead{position:absolute;left:-9999px;top:-9999px}
  .home-table tbody tr{
    display:grid;
    grid-template-columns:minmax(0,1fr) minmax(0,1fr);
    grid-template-areas:"name name" "krank score" "sg10 sg5" "long vol";
    column-gap:8px;row-gap:2px;
    margin-bottom:10px;padding:10px 12px;
    border:1px solid var(--line);border-radius:10px;background:var(--surface);
  }
  .home-table tbody th[scope=row]{grid-area:name;height:auto;padding:0 0 8px;text-align:left;border-bottom:1px solid var(--line);margin-bottom:6px}
  .home-table tbody th[scope=row] .player-name{font-size:1rem}
  /* Resets the desktop table's explicit per-column widths (12rem on
     column 1 and the last column, 9rem on column 2) -- those px/rem
     widths were leaking straight through the cascade onto this grid
     (a `width` declaration on a grid item is a different property from
     `grid-template-columns`, so it is never overridden just because
     this block's own selectors win on specificity for the properties
     they DO set) and forcing the last cell 12rem/192px wide regardless
     of the actual 1fr track width -- the real cause of the residual
     desktop-width-shaped mobile overflow found by measuring every
     cell's real bounding box at 360/390/430px, not assumed. */
  .home-table tbody th[scope=row],.home-table tbody td{min-width:0;width:auto}
  .home-table tbody td{height:auto;padding:6px 8px;border-radius:6px}
  .home-table tbody td.k-rank-cell{grid-area:krank}
  .home-table tbody td:nth-child(3){grid-area:sg10}
  .home-table tbody td:nth-child(4){grid-area:sg5}
  .home-table tbody td.metric-secondary:nth-child(5){grid-area:long}
  .home-table tbody td.metric-secondary:nth-child(6){grid-area:vol}
  .home-table tbody td:nth-child(7){grid-area:score;background:transparent}
  /* The desktop table sets an explicit width (12rem on column 1 and
     the last column, 9rem on column 2 -- .home-table th:nth-child(1),
     .home-table td:nth-child(1)/(2)/last-child) with higher specificity
     than this block's own grid-area selectors on those SAME cells for
     the `width` property specifically (a different property than
     grid-area, so it was never in contention on specificity for the
     rules above and kept applying unopposed through the cascade --
     confirmed by measuring the last cell's real rendered width, which
     stayed a constant 192px/12rem across three different viewports
     instead of following its grid track). Reset explicitly here, on
     selectors specific enough to outrank the desktop rule for width
     too, so every cell's real box finally matches its grid track. */
  .home-table tbody th[scope=row],.home-table tbody td.k-rank-cell,.home-table tbody td:nth-child(7){width:auto}
  .home-table tbody td::before{content:attr(data-label);display:block;color:var(--muted);font-size:.62rem;font-weight:700;letter-spacing:.02em;text-transform:uppercase;margin-bottom:1px}
}
@media(max-width:430px){
  .home-table tbody tr{padding:9px 10px}
  .home-table tbody td{padding:5px 6px}
}
/* v3: player-name column is centered per spec -- this must be the last
   rule touching .home-table th/td:nth-child(1) in this file so it wins
   the cascade over the two earlier (left-align) declarations above.
   Column 1 (OWNER VISUAL REVIEW FAIL, item 4: Player now leads the
   visual hierarchy -- 선수, K-Ranking, 최근 10R SG, 최근 5R SG, then the
   secondary 장기 SG/변동성, then 현재 스코어 last). */
.home-table th:nth-child(1),.home-table td:nth-child(1){text-align:center}
/* Secondary metrics (장기 SG, 변동성) are real data, not hidden, but
   visually de-emphasized relative to the two primary recent-SG columns
   -- smaller and muted, never a wider table to fit them. */
.home-table .metric-secondary{color:var(--muted);font-size:.85em}
.home-table th.metric-secondary{font-weight:700}
.home-summary{display:flex;flex-wrap:wrap;gap:.3rem 1.75rem;max-width:none}.home-summary .stat{display:flex;align-items:baseline;gap:.4rem}
.tournament-row{padding:1rem 1.25rem}.tournament-row .row-cta{display:inline-flex;align-items:center;min-height:32px;margin-top:.5rem;color:var(--green);font-size:.82rem;font-weight:750;text-decoration:none}.tournament-row .stage-pending{color:#9aa39d;cursor:default}
/* v3 Phase 3: Korean headings must never split a word across lines --
   a real user's 1440px browser wrapped "공식 순위와 NEO 검증 순위 비교"
   as "...순위 비\n교", which the desktop-1440 Playwright geometry check
   never caught because it only measured font-size, not wrap points. */
h1,h2,h3,.home-head h1,.page-head h1,.product-hero h1,.tournament-context h1{word-break:keep-all;overflow-wrap:normal}

/* PUBLIC UI Phase 8 -- one immutable brand lockup, used by every page's
   header (see global_navigation.py). "NEO GOLF DATA" plus NUMBER /
   EVIDENCE / ORACLE stacked one per line underneath -- shown on every
   viewport (never hidden on mobile): the legend just shrinks and drops
   its divider below ~480px so the header never pushes nav down. */
.neo-global-brand{display:inline-flex;align-items:center;gap:.55rem;flex:0 0 auto;color:#17202a;text-decoration:none}
.neo-brand-mark{font:850 1.05rem/1 Pretendard,"Apple SD Gothic Neo","Noto Sans KR",sans-serif;letter-spacing:.07em}
.neo-brand-legend{display:flex;flex-direction:column;gap:0;padding-left:.55rem;border-left:1px solid #dfe5ea;line-height:1.15}
.neo-brand-legend__item{display:block;font:650 .58rem/1.15 Pretendard,"Apple SD Gothic Neo","Noto Sans KR",sans-serif;letter-spacing:.05em;color:#65717d;white-space:nowrap}
@media(max-width:480px){.neo-brand-mark{font-size:.85rem}.neo-brand-legend{padding-left:.4rem}.neo-brand-legend__item{font-size:.48rem}}

/* Active-section nav state: green text + underline, matching the legacy
   .global-nav__link[aria-current=page] treatment used elsewhere. */
.neo-global-header .neo-global-nav a.is-active,
.neo-global-header .neo-global-nav a[aria-current=page]{color:#0f5c46;box-shadow:inset 0 -2px #0f5c46}

/* Compact breadcrumb ahead of every tournament page's title -- "which
   tournament, which point in time" must be answerable from the page
   title alone (UX spec 3). */
.breadcrumb{margin:.6rem 0 0;color:var(--muted);font-size:.78rem;font-weight:600}
.breadcrumb a{color:var(--muted);text-decoration:none}
.breadcrumb a:hover,.breadcrumb a:focus-visible{color:var(--green);text-decoration:underline}
.breadcrumb [aria-current=page]{color:var(--ink);font-weight:750}
.breadcrumb__sep{margin:0 .3em;color:#9aa39d}

/* GLOBAL TABLE SYSTEM: every public data table centers numeric/short
   data columns (name, rank, score, probability, SG, sample count) and
   keeps tabular numerals; only genuinely long descriptive text is left
   -- and no such column exists in any current public table, so the
   default now IS center, full stop. thead/tbody share the same rule so
   header and body columns can never drift out of alignment. This is the
   last rule touching .data-table th/td alignment in this file so it
   wins the cascade over the narrower right/left declarations above. */
.data-table th,.data-table td{text-align:center}
.data-table th:nth-child(2),.data-table td:nth-child(2){text-align:center}
.data-table td{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}

/* GLOBAL CHART SYSTEM: the line/story is the point, not the printed
   number -- point-value labels stay modest, and a dense (many-point,
   e.g. hole-by-hole) chart uses an even smaller, tighter scale than a
   sparse (few-checkpoint, e.g. PRE/R1/R2/R3/FINAL) one. */
.chart-value{font-size:14px}
.line-chart--dense .chart-value{font-size:12px;font-weight:600}
.line-chart--dense .chart-x-label,.line-chart--dense .chart-y-label{font-size:12px}
/* Edge-aware label alignment: the first/last point on any axis anchors
   away from the plot edge instead of centering over it, so it can never
   clip past the SVG viewBox (the real "R3 15.04% right clipping" and
   "18번 right clipping" defects found on real screenshots). */
.chart-x-label--start,.chart-value--start{text-anchor:start}
.chart-x-label--end,.chart-value--end{text-anchor:end}
@media(max-width:430px){
  .chart-value{font-size:12px}
  .line-chart--dense .chart-value{font-size:10px}
  .line-chart--dense .chart-x-label,.line-chart--dense .chart-y-label{font-size:10px}
  .chart-end-label{font-size:12px}
}

/* LIVE VISUAL HOTFIX v2: a dense chart's 18 points are no longer all
   permanently labeled (see _select_dense_label_indices in analytics.py)
   -- every point's exact value instead surfaces through this tooltip on
   mouse hover AND keyboard focus (tabindex="0" on .chart-point-wrap, so
   :focus works the same as :hover -- a plain SVG <title> never shows on
   keyboard focus in any browser, which a bare hover-only affordance
   would have silently failed for keyboard users). */
.chart-point-wrap{cursor:pointer}
.chart-point-wrap:focus{outline:none}
.chart-point-wrap:hover circle.chart-point,.chart-point-wrap:focus circle.chart-point{stroke-width:4}
.chart-tooltip{opacity:0;pointer-events:none;transition:opacity .12s ease}
.chart-point-wrap:hover .chart-tooltip,.chart-point-wrap:focus .chart-tooltip{opacity:1}
.chart-tooltip rect{fill:#17202a}
.chart-tooltip text{fill:#fff;font-size:11px;font-weight:700;text-anchor:middle}

/* TOURNAMENT-DAY MODE (script 88 render_clean): while a tournament has
   at least one validated stage, this hero -- not the K-Ranking/NEO
   ranking table -- is HOME's first-screen content. Ranking is not
   deleted, only pushed below (see .ranking-compare-heading below). */
.tournament-day-hero{padding:1.75rem 0 1.5rem;border-bottom:1px solid var(--line)}
.tournament-day-hero h1{margin:.2rem 0 .4rem;max-width:none}
.tournament-day-hero__dates{margin:0 0 1rem;color:var(--muted);font-family:var(--num);font-variant-numeric:tabular-nums}
.tournament-day-hero__facts{display:flex;gap:1.5rem;margin-bottom:1rem}
.tournament-day-hero__facts strong{display:block;font:800 1.3rem var(--num);color:var(--green)}
.tournament-day-hero__facts span{color:var(--muted);font-size:.8rem}
.tournament-day-hero__stage{display:flex;align-items:center;gap:.6rem;margin-bottom:1.1rem;flex-wrap:wrap}
.tournament-day-hero__stage strong{font-size:1.05rem}
.tournament-day-hero__updated{margin:0 0 1.1rem;color:var(--muted);font-size:.78rem;font-family:var(--num);font-variant-numeric:tabular-nums}
/* HOME RANKING H1 FIX: the shared .page-head h1{max-width:22ch} rule
   (elsewhere correctly limiting an editorial-width headline) clips a
   Korean heading long before 22 real characters' worth of space is
   used -- CJK glyphs render close to 2x the width of the Latin "0"
   glyph "ch" is defined from, so 22ch was never really "22 characters"
   for this string ("공식 순위와 NEO 검증 순위 비교", 19 characters
   including spaces) and it wrapped with a lone "비교" as an orphan
   line. Fixed at the true root cause (the width constraint itself, not
   font-size) and scoped to this heading alone via a dedicated class --
   .page-head h1 elsewhere (KG/tournaments-hub/About) is untouched.
   text-wrap:balance additionally keeps a forced mobile wrap from ever
   leaving a lone short trailing line. */
.home-head .ranking-compare-heading{max-width:48rem;text-wrap:balance}
/* PUBLIC UI correction (GLOBAL SPONSOR RULE): the verified sponsor
   must render directly BELOW the player name everywhere -- this was
   previously only true where a page's own local stylesheet happened
   to declare it (OK Open's stage pages); .player-name/.player-sponsor
   (HOME/RANKING and every promotion-time-normalized frozen page) had
   no such rule at all, so the sponsor text ran inline on the same
   line as the name with no visual separation. */
.player-name{display:block;font-weight:700}
.player-sponsor{display:block;color:var(--muted);font-size:.78rem;margin-top:.15rem}
/* PRODUCT RECOVERY V1 REDESIGN: HOME's three tournament cards (지난/
   이번/다음 대회 -- src/klpga/website_v2/tournament_cards.py) are now a
   single compact strip, not three tall equal-height bordered panels --
   this is the real layout fix the earlier "LIVE FAILURE FIX" (below)
   only styled, never restructured. Kicker/name/dates render on one
   slim line each; venue and the kind-specific fact (우승/디펜딩 챔피언)
   sit inside a native <details> that costs zero height until a visitor
   opens it, so the whole strip stays a thin band of secondary
   navigation and the player ranking table underneath it dominates the
   first screen, exactly like the rest of this file's tables/panels
   still do below it. */
.t-tournament-cards{display:flex;margin:1rem 0;background:var(--surface);border:1px solid var(--line)}
.t-tournament-card{flex:1 1 0;min-width:0;padding:.55rem .85rem;border-right:1px solid var(--line)}
.t-tournament-card:last-child{border-right:0}
.t-tournament-card__kicker{margin:0;color:var(--green);font-size:.64rem;font-weight:850;letter-spacing:.08em;text-transform:uppercase}
.t-tournament-card__name{margin:.15rem 0;font-size:.88rem;font-weight:800;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.t-tournament-card__name a{text-decoration:none}
.t-tournament-card__name a:hover{text-decoration:underline}
.t-tournament-card__dates{margin:0;color:var(--muted);font-size:.7rem;font-variant-numeric:tabular-nums;white-space:nowrap}
.t-tournament-card__details{margin-top:.25rem}
.t-tournament-card__details summary{list-style:none;cursor:pointer;color:var(--green);font-size:.7rem;font-weight:750}
.t-tournament-card__details summary::-webkit-details-marker{display:none}
.t-tournament-card__details summary::marker{content:""}
.t-tournament-card__row{display:flex;justify-content:space-between;gap:.75rem;padding:.25rem 0;border-top:1px solid var(--line);font-size:.76rem}
.t-tournament-card__row:first-of-type{margin-top:.3rem}
.t-tournament-card__row dt{margin:0;color:var(--muted)}
.t-tournament-card__row dd{margin:0;font-weight:700;text-align:right}
/* OWNER VISUAL REVIEW FAIL, item 2 (CURRENT TOURNAMENT STRIP): all
   three cards read as equally weighted -- the strip must stay compact
   (no return to the old three-large-card layout) but 이번 대회 (the
   real current/upcoming tournament) needs to read as clearly primary,
   지난/다음 as secondary. Done entirely through weight/color/size within
   the same one-row strip -- current gets more flex width, an accent
   left border and tint, and a larger name; last/next shrink and mute. */
.t-tournament-card[data-tournament-card="current"]{flex:1.5 1 0;background:var(--green-2);border-left:3px solid var(--green)}
.t-tournament-card[data-tournament-card="current"] .t-tournament-card__name{font-size:1.05rem}
.t-tournament-card[data-tournament-card="last"],.t-tournament-card[data-tournament-card="next"]{flex:0.8 1 0;opacity:.8}
.t-tournament-card[data-tournament-card="last"] .t-tournament-card__name,.t-tournament-card[data-tournament-card="next"] .t-tournament-card__name{font-size:.8rem}

/* PLAYER INTELLIGENCE (Sprint 3): integration only, no new visual
   system -- every rule below reuses the page's own tokens
   (--ink/--muted/--green/--green-2/--surface/--panel/--line/--gold/--red)
   and existing structural classes (.hero-data, .evidence-detail,
   .section-heading, .data-table, .table-scroll, .label-chip). The 12
   non-hero sections are native <details>/<summary> -- costs zero JS,
   matches the tournament-card convention already established above. */
.pi-hero__type{margin:.4rem 0}
.pi-hero__type-en{display:block;margin-top:.15rem;font-size:.7em;font-weight:600;opacity:.75}
.pi-hero__meta{color:var(--muted);font-size:.85rem}
.pi-section{margin:0 0 1rem;border:1px solid var(--line);background:var(--surface)}
.pi-section .section-heading{padding:1rem 1.25rem;margin:0}
.pi-section__body{padding:0 1.25rem 1.25rem}
.pi-empty{color:var(--muted)}
.pi-radar{display:block;width:100%;max-width:22rem;height:auto;margin:0 auto}
.pi-radar-grid{fill:none;stroke:var(--line);stroke-width:1}
.pi-radar-fill{fill:var(--green-2);stroke:var(--green);stroke-width:2}
.pi-radar-label{font-family:var(--font);font-size:11px;font-weight:700;fill:var(--muted)}
.pi-radar-legend{list-style:none;margin:.75rem 0 0;padding:0;display:grid;grid-template-columns:repeat(2,1fr);gap:.35rem;font-size:.85rem}
.pi-kpi-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));gap:.75rem}
.kpi-block{display:grid;gap:.25rem;padding:1rem;background:var(--panel)}
.kpi-label{color:var(--muted);font-size:.78rem}
.kpi-value{font:800 1.5rem var(--num);color:var(--green)}
.pi-metric-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.4rem}
.pi-reason-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.6rem}
.pi-reason{display:flex;flex-direction:column;gap:.3rem}
.label-chip--positive{background:var(--green-2);color:var(--green)}
.label-chip--negative{background:#f3e5e2;color:var(--red)}
.pi-evolution-list{list-style:none;margin:.5rem 0 0;padding:0}
.pi-verdict{margin-top:1.5rem;padding:1.4rem;border:2px solid var(--ink);background:var(--ink);color:var(--paper)}
.pi-verdict summary{color:#fff;cursor:pointer}
.pi-verdict h2{margin:0 0 .5rem;color:#fff;display:inline}
.pi-verdict p{margin:.75rem 0 0;color:var(--paper)}
.pi-generating{text-align:center;padding:3rem 1.4rem}
.player-prev-next{display:flex;justify-content:space-between;gap:1rem;margin-bottom:1rem;font-weight:750}
.player-prev-next a{text-decoration:none;color:var(--green)}
/* The mobile @media(max-width:760px){.table-scroll{overflow-x:visible}}
   rule above (line ~105) was scoped to .home-table's own card-layout
   mobile technique, which compensates with its own .home-table{min-
   width:0} reset right after it -- but the selector itself is bare
   .table-scroll, so it silently strips scroll-containment from every
   OTHER page's .table-scroll too. .pi-section's own .data-table (plain
   min-width:42rem, no mobile card layout) needs the real overflow-x:auto
   back, restored here with higher specificity rather than editing the
   shared rule (which HOME/RANKING's mobile layout still depends on). */
.pi-section .table-scroll{overflow-x:auto}
/* PLAYER HISTORY V5: #ph-career-rolling-trend's decomposition tables
   sit as a plain <div> sibling of the .pi-section <details> elements
   (deliberately -- the mission requires "no new cards"/no new
   <details> wrapper), so the .pi-section .table-scroll fix above does
   not reach them and they fall back to the same bare mobile
   .table-scroll{overflow-x:visible} reset documented above, causing a
   real 336px page-level horizontal overflow at 390px (caught by
   screenshot QA). Scoped directly to this block's id instead of
   reusing .pi-section, which also carries its own border/background/
   margin that would visually change this block. */
#ph-career-rolling-trend .table-scroll{overflow-x:auto}
/* MISSION V60 (2026-09-28): #ph-dna-growth-velocity's table is the same
   pattern -- a plain <div class="ph-evo-block"> sibling, not a
   .pi-section, so it also fell through to the bare mobile
   .table-scroll{overflow-x:visible} reset, causing a real 315px
   page-level horizontal overflow at 390px (caught by screenshot QA). */
#ph-dna-growth-velocity .table-scroll{overflow-x:auto}
/* MISSION V71 (2026-09-28): Layer 1 ("Story") -- five real answer
   cards at the very top of Player History, each linking down to the
   full Layer 2 ("Evidence") section beneath it.
   MISSION V72 (2026-09-28): "Transform the Story layer from a
   dashboard into a magazine cover... the first screen must look like
   the cover of a premium golf magazine, not a KPI dashboard." The
   conclusion headline is now the dominant visual element (bigger,
   heavier, tighter line-height -- a magazine pull-quote, not a KPI
   number) with the supporting numbers demoted to a small caption
   beneath it, reversing the old question-then-number dashboard order. */
.ph-story-layer{margin:0 0 1.5rem}
.ph-story-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(13rem,1fr));gap:.75rem}
.ph-story-card{display:block;padding:1.3rem 1.2rem;background:var(--surface);border:1px solid var(--line);
  border-left:3px solid var(--green);text-decoration:none;color:inherit}
.ph-story-card:hover{background:var(--panel)}
.ph-story-label{margin:0 0 .35rem;font-size:.68rem;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
.ph-story-headline{margin:0 0 .3rem;font-size:2rem;font-weight:800;line-height:1.1;color:var(--ink);font-variant-numeric:tabular-nums}
.ph-story-subtitle{margin:0 0 .5rem;font-size:.85rem;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
.ph-story-footer{margin:0;font-size:.7rem;font-weight:500;color:var(--muted);font-variant-numeric:tabular-nums}
.ph-layer2-marker{margin:2rem 0 .75rem;padding-top:1rem;border-top:1px solid var(--line);
  font-size:.75rem;font-weight:700;letter-spacing:.05em;color:var(--muted)}
/* MISSION V73 (2026-09-28): Season Replay chart redesign -- "tournament
   names ... visible on desktop." At narrow widths the same rotated
   labels for 15-25 real tournaments would overlap into an unreadable
   smear, so they hide below the tablet breakpoint; the win/top10/peak/
   slump/recovery marks and their <title> tooltips (the real per-point
   detail) stay at every width. */
@media(max-width:900px){.ph-season-label{display:none}}
/* Simple 2-column label/value stat tables (Current Form, Shot Profile)
   never need the generic .data-table's min-width:42rem (that width
   exists for wide multi-column leaderboard tables elsewhere on the
   site) -- forcing it here just pushes the value column off-screen on
   mobile, the opposite of "numbers first, no horizontal scrolling". */
.pi-kv-table{min-width:0;width:100%}
.pi-kv-table td{text-align:right;font-weight:700}
@media(max-width:760px){.pi-radar-legend{grid-template-columns:1fr}.pi-kpi-grid{grid-template-columns:repeat(2,1fr)}}

/* Player Intelligence Report (question-organized, playerCode=10097 only,
   player_intelligence_10097_report.py). New, additive classes scoped
   with a piq- prefix -- never redefines any selector above, so every
   other page keeps rendering exactly as it did before this block. */
.piq-step{margin:0 0 .9rem;line-height:1.6}
.piq-label,.piq-step-label{display:inline-block;margin-right:.5rem;padding:.15rem .5rem;background:var(--ink);color:var(--paper);font-size:.68rem;font-weight:800;letter-spacing:.04em;text-transform:uppercase;vertical-align:middle}
.piq-label-standalone{margin:0 0 .4rem}
.piq-evidence-list{list-style:none;margin:0 0 .9rem;padding:0;display:flex;flex-direction:column;gap:.4rem}
.piq-evidence-list li{padding-left:1rem;border-left:2px solid var(--line);color:var(--muted);font-size:.9rem;line-height:1.55}
.piq-conclusion{padding:.85rem 1rem;background:var(--green-2);border-left:3px solid var(--green)}
.piq-brief{display:grid;gap:.5rem;margin:0 0 .9rem;padding:.85rem 1rem;background:var(--panel);border-left:3px solid var(--line)}
.piq-brief p{margin:0;font-size:.88rem;line-height:1.55}
.piq-brief strong{color:var(--muted);font-size:.75rem;text-transform:uppercase;letter-spacing:.03em;display:block;margin-bottom:.15rem}
.ph-page .piq-brief--positive{border-left-color:var(--green)}
.ph-page .piq-brief--positive strong{color:var(--green)}
.ph-page .piq-brief--negative{border-left-color:var(--red)}
.ph-page .piq-brief--negative strong{color:var(--red)}
.piq-audit{display:flex;flex-wrap:wrap;gap:.4rem;margin-top:.75rem}
.piq-why-this-matters{margin:1rem 0 0;padding:.85rem 1rem;background:var(--ink);color:var(--paper);font-weight:700;line-height:1.5}
.piq-why-this-matters .piq-label{background:var(--paper);color:var(--ink)}
.piq-action{margin:.6rem 0 0;padding:.85rem 1rem;background:var(--green);color:#fff;font-weight:700;line-height:1.5;border:2px solid var(--ink)}
.piq-action .piq-label{background:#fff;color:var(--green)}
.piq-excluded-list{margin:.75rem 0 0;padding-left:1.1rem;color:var(--muted);font-size:.9rem;line-height:1.6}
.piq-excluded-list li{margin-bottom:.5rem;overflow-wrap:anywhere;word-break:break-word}
.piq-roadmap-list{list-style:none;margin:.75rem 0 0;padding:0;display:flex;flex-direction:column;gap:.9rem}
.piq-roadmap-item{padding:.85rem 1rem;border:1px solid var(--line);background:var(--panel)}
.piq-roadmap-item .piq-step:last-of-type{margin-bottom:.4rem}
.ph-evo-block{padding:.85rem 1rem;border:1px solid var(--line);background:var(--panel);margin-bottom:.9rem}
/* MISSION V60 (2026-09-28): "expand every chart to use the full
   content width." width:100% (not max-width) so every trend/bar/
   heatmap chart stretches to fill its column on a wide desktop,
   instead of sitting at a fixed pixel width inside a much wider
   container -- viewBox + height:auto keeps every chart's real
   internal proportions correct at any rendered width. */
.ph-spark{display:block;margin:.4rem 0;width:100%;height:auto}
/* A radar's own shape only reads correctly near-square -- letting it
   stretch to the full width of a wide desktop column would distort
   it into an oval, not "use the space better." Capped, not full-
   width, by design for this one chart type. */
.ph-spark--radar{width:auto;max-width:100%}
.ph-evo-block svg[role="img"]{max-width:100%;height:auto}
.piq-sg-missing{color:var(--muted);font-style:italic;text-align:center!important}
/* MISSION V77 REDESIGN (2026-09-28): Career Timeline as an editorial
   graphic. "Desktop width should use approximately 80~90% of the
   available width... avoid tiny centered graphics" -- less than every
   other chart's full 100% (.ph-spark above), so it reads as a
   deliberately composed graphic rather than a stretched dashboard
   chart. "Mobile: convert to a vertical timeline" -- the SVG and the
   vertical list render the exact same real points; only one is ever
   visible. Placed AFTER .ph-spark on purpose: that rule's own
   unconditional display:block has equal (0,1,0) specificity, so an
   earlier .ph-timeline-svg{display:none} would lose the cascade to it
   at any width regardless of the media query -- source order after
   .ph-spark is what makes the override actually win. */
.ph-timeline-svg{width:85%;margin:0 auto;display:block}
.ph-timeline-mobile{display:none}
@media(max-width:760px){
  .ph-timeline-svg{display:none}
  .ph-timeline-mobile{display:block;margin:.5rem 0 1rem}
  .ph-timeline-mobile-row{display:grid;grid-template-columns:20px 1fr auto;align-items:center;
    gap:.75rem;position:relative;padding:.9rem 0}
  .ph-timeline-mobile-row::before{content:"";position:absolute;left:9px;top:0;bottom:0;width:2px;background:var(--line)}
  .ph-timeline-mobile-row:first-child::before{top:50%}
  .ph-timeline-mobile-row:last-child::before{bottom:50%}
  .ph-timeline-mobile-icon{width:18px;height:18px;z-index:1;justify-self:center;position:relative}
  .ph-timeline-mobile-title{font-size:16px;font-weight:500;color:var(--ink)}
  .ph-timeline-mobile-year{font-size:13px;color:var(--muted);font-variant-numeric:tabular-nums}
  .ph-timeline-mobile-icon--circle{border-radius:50%;background:#8a988f}
  .ph-timeline-mobile-icon--star{background:#c98a1a;clip-path:polygon(50% 0%,61% 35%,98% 35%,68% 57%,79% 91%,50% 70%,21% 91%,32% 57%,2% 35%,39% 35%)}
  .ph-timeline-mobile-icon--triangle{background:#0f5c46;clip-path:polygon(50% 0%,100% 100%,0% 100%)}
  .ph-timeline-mobile-icon--diamond{width:14px;height:14px;background:#0f5c46;transform:rotate(45deg);justify-self:center}
  .ph-timeline-mobile-icon--ring{border:2px solid #0f5c46;border-radius:50%}
  .ph-timeline-mobile-icon--ring::after{content:"";position:absolute;inset:3px;border-radius:50%;background:#0f5c46}
}

/* V6 mission (2026-09-25): Current Form's headline stat -- the one
   number the whole page leads with (current form vs her own career
   baseline), styled like a real DataGolf-style hero stat instead of
   being one chip among several identical-looking chips. */
.ph-hero-stat-block{margin-bottom:.9rem}
.ph-hero-stat-label{margin:0 0 .1rem;color:var(--muted);font-size:.78rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em}
.ph-hero-stat{margin:0;font-size:clamp(2.4rem,7vw,3.4rem);font-weight:800;line-height:1;letter-spacing:-.02em;color:var(--ink)}
.ph-hero-stat--positive{color:var(--green)}

/* MISSION "30초 스캔" (2026-09-27), approved wireframe:
   https://claude.ai/artifact/BZBJhzA36ZvskuKPkDjyv7 -- "읽게 하지 말고
   보이게 만들어라... 사용자는 읽는 것이 아니라 훑는다." Every rule
   below replaces a sentence/chip/table with a number, arrow, badge, or
   dot the eye can scan in seconds -- no new data, only new display of
   what already renders elsewhere on this page. */
.ph-scan-stats{display:flex;gap:2rem;align-items:flex-end;flex-wrap:wrap;margin-top:.6rem}
.ph-scan-stat{display:flex;flex-direction:column;gap:.1rem}
.ph-scan-stat-num{font-size:1.6rem;font-weight:800;color:var(--ink);line-height:1}
.ph-scan-stat-lbl{font-size:.72rem;color:var(--muted)}
.ph-scan-trend{display:flex;align-items:center;gap:.4rem;font-size:.95rem;font-weight:700;color:var(--muted);margin-left:auto}
.ph-scan-trend--up{color:var(--green)}
.ph-scan-trend--down{color:var(--red)}
.ph-scan-trend-arrow{font-size:1.3rem;line-height:1}

.ph-arrow-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:1rem;margin-top:.75rem}
.ph-arrow-card{text-align:center;padding:1rem .5rem;background:var(--panel)}
.ph-arrow-card .ph-arrow-big{display:block;font-size:2rem;line-height:1;color:var(--green)}
.ph-arrow-card--down .ph-arrow-big{color:var(--red)}
.ph-arrow-card .ph-arrow-lbl{font-size:.8rem;font-weight:800;color:var(--ink);margin-top:.3rem}
.ph-arrow-card .ph-arrow-num{font-size:.72rem;color:var(--muted);margin-top:.1rem}
/* MISSION V41 (2026-09-28): the smallest of these same four real
   deltas, labeled directly on its own card -- the page's one answer
   to "what is the current weakness?" A coach-eye pass on the first
   version found the plain gray caption disappeared next to three
   identical green "improving" cards -- a small gold pill (gold, not
   red: this component is still real +, never a decline) now gives it
   enough contrast to survive a 15-second scan. */
.ph-arrow-weakest-tag{display:inline-block;font-size:.62rem;font-weight:700;color:#7a5610;background:#f3e6c8;border-radius:.7rem;padding:.1rem .45rem;margin-top:.3rem}

.ph-form-strip{display:flex;gap:.35rem;align-items:center;flex-wrap:wrap;padding:.4rem 0}
.ph-form-dot{width:1.15rem;height:1.15rem;border-radius:50%;background:#c3cec7;display:inline-flex;align-items:center;justify-content:center;font-size:.6rem;flex-shrink:0}
.ph-form-dot--win{background:var(--gold);color:#fff}
.ph-form-dot--top10{background:var(--green)}
.ph-form-strip-axis{display:flex;justify-content:space-between;font-size:.72rem;color:var(--muted);margin-top:.25rem}

.ph-identity-badge{display:inline-block;background:var(--green);color:#fff;font-size:1.15rem;font-weight:800;padding:.5rem 1.25rem;border-radius:999px;margin-bottom:.6rem}

.ph-round-pair{display:flex;gap:1.5rem}
.ph-round-big{flex:1;text-align:center;padding:1.1rem;background:var(--panel)}
.ph-round-big-lbl{font-size:.78rem;color:var(--muted);margin-bottom:.3rem}
.ph-round-big-num{font-size:clamp(1.5rem,6vw,2.2rem);font-weight:800;line-height:1;color:var(--ink);white-space:nowrap}
.ph-round-big--positive .ph-round-big-num{color:var(--green)}
.ph-round-big--negative .ph-round-big-num{color:var(--red)}
.ph-round-big-cap{font-size:.75rem;color:var(--muted);margin-top:.5rem}

/* MISSION V31 (2026-09-28): Skill Chain -- Skill -> Scoring Opportunity
   -> Scoring -> Result -> Career, five real already-computed facts in
   one row. */
.ph-skill-chain{display:flex;align-items:center;gap:.4rem;flex-wrap:wrap;margin-top:.9rem}
.ph-chain-stage{flex:1;min-width:6.5rem;text-align:center;padding:.7rem .4rem;background:var(--panel)}
.ph-chain-stage-lbl{font-size:.66rem;color:var(--muted);text-transform:uppercase;letter-spacing:.03em}
.ph-chain-stage-num{font-size:1rem;font-weight:800;color:var(--ink);margin-top:.15rem}
.ph-chain-arrow{font-size:1.1rem;color:var(--muted);flex-shrink:0}

/* RED TEAM (2026-09-25): Career Form Story -- narrative-first stage
   cards (Early/Mid/Late Season, Peak Form, Current Form). Mirrors
   .piq-brief's card treatment so the story reads as a highlight reel,
   not a stats table. */
.ph-form-story{display:grid;gap:.6rem;margin-bottom:.9rem}
.ph-form-stage{padding:.85rem 1rem;background:var(--panel);border-left:3px solid var(--green)}
.ph-form-stage .piq-step-label{margin-bottom:.3rem}

/* NEO PLAYER BIOGRAPHY V4 (2026-09-25): Career Story cards (told
   backwards -- Current, then Winning Stage/Breakthrough/Development/
   Adaptation). Same card treatment as .ph-form-stage above, distinct
   class so the two narrative features never collide in selectors. */
.ph-bio-story{display:grid;gap:.6rem;margin-bottom:.9rem}
.ph-bio-stage{padding:.85rem 1rem;background:var(--panel);border-left:3px solid var(--green)}
.ph-bio-stage .piq-step-label{margin-bottom:.3rem}

/* V5 mission (2026-09-25): a small native <details> nested INSIDE an
   existing section body (e.g. Course Profile's full table) -- never a
   new top-level card, just a disclosure toggle for detail a 30-second
   read does not need up front. */
.ph-nested-detail{margin-top:.75rem}
.ph-nested-detail summary{cursor:pointer;font-weight:700;font-size:.85rem;color:var(--green);padding:.3rem 0}

/* Player DNA season selector -- pure CSS radio tabs, zero JS (RED TEAM
   mission F). Radios are visually hidden; order-based :nth-of-type
   pairing between .ph-dna-radio and both the matching label and the
   matching panel means this stays correct regardless of how many
   seasons a given player has, with no per-season CSS needed. */
.ph-dna-radio{position:absolute;opacity:0;width:1px;height:1px;pointer-events:none}
.ph-dna-tab-bar{display:flex;flex-wrap:wrap;gap:.4rem;margin-bottom:.9rem}
.ph-dna-tab-label{display:inline-flex;align-items:center;min-height:40px;padding:.35rem .9rem;border:1px solid var(--line);background:var(--surface);color:var(--muted);font-weight:750;font-size:.85rem;cursor:pointer}
.ph-dna-panel{display:none}
.ph-dna-radio:nth-of-type(1):checked ~ .ph-dna-tab-bar .ph-dna-tab-label:nth-of-type(1){background:var(--green);color:#fff;border-color:var(--green)}
.ph-dna-radio:nth-of-type(2):checked ~ .ph-dna-tab-bar .ph-dna-tab-label:nth-of-type(2){background:var(--green);color:#fff;border-color:var(--green)}
.ph-dna-radio:nth-of-type(3):checked ~ .ph-dna-tab-bar .ph-dna-tab-label:nth-of-type(3){background:var(--green);color:#fff;border-color:var(--green)}
.ph-dna-radio:nth-of-type(4):checked ~ .ph-dna-tab-bar .ph-dna-tab-label:nth-of-type(4){background:var(--green);color:#fff;border-color:var(--green)}
.ph-dna-radio:nth-of-type(5):checked ~ .ph-dna-tab-bar .ph-dna-tab-label:nth-of-type(5){background:var(--green);color:#fff;border-color:var(--green)}
.ph-dna-radio:nth-of-type(6):checked ~ .ph-dna-tab-bar .ph-dna-tab-label:nth-of-type(6){background:var(--green);color:#fff;border-color:var(--green)}
.ph-dna-radio:nth-of-type(1):checked ~ .ph-dna-panels .ph-dna-panel:nth-of-type(1){display:block}
.ph-dna-radio:nth-of-type(2):checked ~ .ph-dna-panels .ph-dna-panel:nth-of-type(2){display:block}
.ph-dna-radio:nth-of-type(3):checked ~ .ph-dna-panels .ph-dna-panel:nth-of-type(3){display:block}
.ph-dna-radio:nth-of-type(4):checked ~ .ph-dna-panels .ph-dna-panel:nth-of-type(4){display:block}
.ph-dna-radio:nth-of-type(5):checked ~ .ph-dna-panels .ph-dna-panel:nth-of-type(5){display:block}
.ph-dna-radio:nth-of-type(6):checked ~ .ph-dna-panels .ph-dna-panel:nth-of-type(6){display:block}
.piq-protocol{margin:.5rem 0 0;padding:.85rem 1rem;background:var(--surface);border:1px solid var(--line);border-bottom:0;display:grid;grid-template-columns:12rem 1fr;gap:.35rem .8rem;font-size:.85rem}
.piq-protocol dt{font-weight:700;color:var(--muted);text-transform:uppercase;font-size:.72rem;letter-spacing:.03em;padding-top:.1rem}
.piq-protocol dd{margin:0;line-height:1.5}
.piq-current-status{display:flex;flex-wrap:wrap;gap:.4rem;padding:.85rem 1rem;background:var(--panel);border:1px solid var(--line);border-top:0}
.piq-current-detail{margin:.5rem 0 0;padding:0 1rem .85rem;background:var(--panel);border:1px solid var(--line);border-top:0;font-size:.85rem;color:var(--muted);line-height:1.5}
.piq-checklist{list-style:none;margin:.75rem 0 0;padding:0;display:flex;flex-direction:column;gap:.5rem}
.piq-checklist li{padding:.5rem .75rem;border:1px solid var(--line);font-size:.88rem;line-height:1.6}
.piq-checklist a{color:var(--green);font-weight:700}
@media(max-width:760px){.piq-protocol{grid-template-columns:1fr}.piq-protocol dt{padding-top:.5rem}}

/* Player Intelligence UI refactor (Gold Standard, playerCode=10097 only):
   conclusion-first hierarchy. Still additive piq- classes, still the
   same tokens (--ink/--green/--green-2/--panel/--surface/--line/--muted)
   and the same <details>/<summary> disclosure pattern already used
   throughout this file -- only visual weight and default visibility
   change. .piq-conclusion/.piq-why-this-matters/.piq-action above are
   unused by the 10097 renderer now but stay defined; nothing else
   references removing them. */
.piq-hero-conclusion{margin:0 0 .6rem;padding:1.1rem 1.25rem;background:var(--green);color:var(--surface);font-weight:800;font-size:clamp(1.05rem,2.3vw,1.3rem);line-height:1.45;border:2px solid var(--ink)}
.piq-why-brief{margin:0 0 .9rem;padding-left:.8rem;border-left:3px solid var(--gold);font-size:1rem;font-weight:650;line-height:1.55;color:var(--ink)}
.piq-monitoring-summary{margin-top:.9rem;border-top:1px solid var(--line)}
.piq-evidence-toggle{margin-top:.9rem}
.piq-evidence-toggle>summary{display:inline-flex;align-items:center;min-height:36px;padding:.3rem .65rem;color:var(--muted);font-size:.8rem;font-weight:750;letter-spacing:.02em;cursor:pointer;border:1px solid var(--line);background:var(--panel)}
.piq-evidence-toggle[open]>summary{color:var(--green);border-color:var(--green)}
.piq-evidence-toggle__body{margin-top:.85rem}
@media(max-width:760px){.t-tournament-cards{flex-direction:column}.t-tournament-card{border-right:0;border-bottom:1px solid var(--line)}.t-tournament-card:last-child{border-bottom:0}.t-tournament-card[data-tournament-card="current"]{border-left:3px solid var(--green)}}

/* MISSION V8 (2026-09-25), playerCode=10097 only: "Freeze the
   architecture... improve only visual hierarchy, typography, spacing,
   reading speed." No section, card, chart, or data field changes here
   -- every rule below is scoped under .ph-page (the wrapper
   render_player_history_html now emits) so nothing leaks onto
   player_intelligence_10097_report.py or player_intelligence_9431_
   report.py, which render the same shared piq- and .pi-section classes
   for a different player. */

/* MISSION V60 (2026-09-28): "design for a 27-inch desktop first...
   the page should feel like a premium sports analytics dashboard, not
   a database export." The shared site-wide content column (main,
   var(--max) = 70rem) is a good width for reading paragraphs, a
   cramped one for a chart-dense page -- widened here ONLY for Player
   History's own <main> (main:has(.ph-page), well-supported since
   2023) so this stays this one page's own decision, never the site-
   wide default every other page still uses. */
main:has(.ph-page){width:min(calc(100% - 2rem),96rem)}

/* The repeated black-pill step label (.piq-step-label.piq-label-
   standalone) is used 18+ times across this one page -- season
   captions, chapter names, table captions, chart captions -- every one
   rendered at the same maximum visual volume. That uniform loudness is
   exactly what made scrolling feel heavier with every section: nothing
   was allowed to recede. Restyled as a plain green eyebrow label (the
   same idiom this site already uses for .section-label/.kicker
   elsewhere) instead of a solid dark badge -- still fully legible,
   still always in the same place, just no longer shouting. */
.ph-page .piq-step-label.piq-label-standalone{
  display:block;background:none;color:var(--green);padding:0;
  font-size:.72rem;font-weight:850;letter-spacing:.07em;margin:0 0 .5rem;
}

/* Un-numbered subordinate sections (시즌 리플레이, 시즌 변화 하이라이트,
   홀 기록) rendered at the exact same visual weight as the 11 numbered
   primary sections -- a reader could not tell "here is one of the
   page's 11 real answers" from "here is a supporting detail block" by
   looking. Demoted: a lighter panel background instead of white,
   a visibly smaller heading than the numbered sections use, and a
   muted (not green) heading color -- still fully open, still fully
   real data, just no longer competing for the same attention as the
   page's actual 11 answers. */
.ph-page .pi-section--sub{background:var(--panel)}
.ph-page .pi-section--sub .section-heading h2{font-size:1.05rem;color:var(--muted);font-weight:750}

/* Slightly more breathing room between sections than the shared
   .pi-section default (used by every other Player Intelligence page,
   left untouched) -- with 18 stacked sections/blocks on this one page,
   an extra quarter-rem between each makes every scroll register as a
   clean break instead of one continuous wall. */
.ph-page .pi-section{margin-bottom:1.4rem}

/* MISSION V11 (2026-09-25): a single early-visibility trust line in
   the hero -- "how much should I trust this" answered before the
   reader scrolls past ten sections, without adding a chip to the
   hero's own tightly-tuned chip row (see MISSION V8). Quiet by
   design: small, muted, a checkmark rather than a loud badge. */
.ph-trust-line{margin:.5rem 0 0;color:var(--green);font-size:.82rem;font-weight:750}
.ph-trust-line::before{content:"✓ ";font-weight:800}

/* MISSION V50 (2026-09-28): the one small trust block left at the
   bottom of Player History once every technical section moved to the
   separate Data Quality Report -- four real numbers, no pipeline
   vocabulary, one link out for anyone who wants the technical detail. */
.ph-trust-block{background:var(--panel);padding:1.4rem 1.2rem;margin-top:.5rem;text-align:center}
.ph-trust-block-title{font-size:.72rem;font-weight:800;letter-spacing:.08em;color:var(--muted);margin:0 0 .8rem}
.ph-trust-headline{display:flex;align-items:baseline;justify-content:center;gap:.5rem;margin-bottom:1rem}
.ph-trust-headline-num{font-size:2.2rem;font-weight:800;color:var(--green);line-height:1}
.ph-trust-headline-lbl{font-size:.85rem;color:var(--muted)}
.ph-trust-stats{display:flex;justify-content:center;gap:1.8rem;flex-wrap:wrap;margin-bottom:1rem}
.ph-trust-stat{display:flex;flex-direction:column;align-items:center}
.ph-trust-stat-num{font-size:1.3rem;font-weight:750;color:var(--ink)}
.ph-trust-stat-lbl{font-size:.72rem;color:var(--muted);margin-top:.15rem}
.ph-trust-link{font-size:.82rem;font-weight:700;color:var(--green)}

/* MISSION V50: the Data Quality Report page shell -- same base
   typography as Player History (.ph-page), a distinct small header so
   it never reads as a continuation of the product page. */
.ph-dq-header{padding:1.4rem 0 .6rem}
.ph-dq-back{margin:.6rem 0 0}
.ph-dq-back a{font-size:.85rem;font-weight:700;color:var(--green)}

/* MISSION V12 (2026-09-25): a collapsed section on this page (a plain
   <details> with no `open` attribute) rendered as a bare green heading
   with nothing visibly below it -- .evidence-detail summary's own
   `display:flex` (needed for the heading/chip layout) silently
   suppresses the browser's native ▶ disclosure triangle, and nothing
   ever replaced it. A first-time reader had no way to tell "this is
   collapsed, click it" from "this is empty/broken" -- exactly the
   moment this mission targets: the eye stops, the reader must guess.
   One small chevron, flipping on [open], fixes every collapsed
   section (and every nested "more" toggle, which shares the same
   descendant selector) in one place. Scoped to .ph-page only --
   .evidence-detail is a shared, site-wide class used by other pages
   this mission does not touch. */
.ph-page .evidence-detail summary::after{content:"▸";margin-left:.75rem;color:var(--muted);font-size:.85em;flex-shrink:0}
.ph-page .evidence-detail[open]>summary::after{content:"▾";color:var(--green)}
