@import url('https://fonts.googleapis.com/css2?family=Prompt:wght@300;400;500;600;700&display=swap');
:root{--ink:#0f0f0f;--muted:#6d6d6d;--paper:#ffffff;--card:#ffffff;--line:#e5e5e5;--red:#0f0f0f;--lime:#ffffff;--night:#ffffff;--r:16px;--max:1480px}*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:var(--paper);color:var(--ink);font-family:'Prompt',sans-serif;font-weight:400;line-height:1.55;-webkit-font-smoothing:antialiased}body.no-scroll{overflow:hidden}a{color:inherit;text-decoration:none}img{display:block;width:100%}button,input,select,textarea{font:inherit}.container{width:min(calc(100% - 48px),var(--max));margin:auto}.section{padding:68px 0}.compact{padding:46px 0}.kicker{display:inline-flex;align-items:center;gap:8px;font-size:10px;font-weight:600;letter-spacing:.12em;text-transform:uppercase}.kicker:before{content:'';width:20px;height:2px;background:var(--red)}.muted{color:var(--muted)}.small{font-size:11px}.badge{display:inline-flex;padding:6px 10px;border-radius:999px;background:var(--red);color:#fff;font-size:9px;font-weight:600;letter-spacing:.08em}.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:42px;padding:0 17px;border:1px solid var(--ink);border-radius:999px;background:var(--ink);color:#fff;font-size:12px;font-weight:500;cursor:pointer}.btn.red{background:var(--red);border-color:var(--red)}.btn.light{background:#fff;color:var(--ink);border-color:#fff}.btn.ghost{background:transparent;color:var(--ink)}.btn.wide{width:100%}.icon-btn{width:40px;height:40px;border:0;background:transparent;border-radius:50%;display:grid;place-items:center;font-size:19px;cursor:pointer}.icon-btn:hover{background:rgba(0,0,0,.06)}.utility{background:var(--ink);color:#fff;font-size:10px}.utility .container{height:30px;display:flex;align-items:center;justify-content:space-between}.live{display:flex;align-items:center;gap:7px}.dot{width:7px;height:7px;border-radius:50%;background:var(--red);box-shadow:0 0 0 4px rgba(255,75,43,.18)}.site-header{position:sticky;top:0;z-index:50;background:rgba(244,241,235,.94);backdrop-filter:blur(14px);border-bottom:1px solid var(--line)}.mainbar{min-height:68px;display:grid;grid-template-columns:200px 1fr 200px;align-items:center;gap:20px}.brand{display:inline-flex;align-items:center;gap:9px;font-size:27px;font-weight:700;letter-spacing:-.06em}.brand-mark{width:12px;height:12px;background:var(--red);border-radius:2px;transform:rotate(10deg)}.nav{display:flex;justify-content:center;gap:22px}.nav a{font-size:12px;font-weight:400;position:relative}.nav a:after{content:'';position:absolute;left:0;right:100%;bottom:-9px;height:2px;background:var(--red);transition:.2s}.nav a:hover:after,.nav a.active:after{right:0}.actions{display:flex;justify-content:flex-end;align-items:center;gap:2px}.cart-icon{position:relative}.cart-icon sup{position:absolute;right:0;top:1px;width:15px;height:15px;border-radius:50%;background:var(--red);color:#fff;display:grid;place-items:center;font-size:8px}.topics{border-top:1px solid var(--line);overflow:auto}.topics .container{min-height:34px;display:flex;align-items:center;gap:22px;white-space:nowrap}.topics a{font-size:10px;color:#5d5a56}.topics b{font-size:9px;color:var(--red);letter-spacing:.12em}.backdrop{position:fixed;inset:0;background:rgba(0,0,0,.45);z-index:80;opacity:0;visibility:hidden;transition:.2s}.backdrop.active{opacity:1;visibility:visible}.drawer{position:fixed;left:0;top:0;bottom:0;width:min(390px,90vw);z-index:90;background:var(--paper);padding:24px;transform:translateX(-105%);transition:.26s;display:flex;flex-direction:column}.drawer.active{transform:none}.drawer-head{display:flex;align-items:center;justify-content:space-between;padding-bottom:20px;border-bottom:1px solid var(--line)}.drawer-nav{display:grid;padding:18px 0}.drawer-nav a{font-size:22px;font-weight:400;padding:10px 0;border-bottom:1px solid var(--line)}.drawer-foot{margin-top:auto;border-top:1px solid var(--line);padding-top:18px}.search-panel{position:fixed;left:0;right:0;top:0;z-index:95;background:var(--paper);transform:translateY(-105%);transition:.26s;border-bottom:1px solid var(--line)}.search-panel.active{transform:none}.search-inner{padding:30px 0}.search-row{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:15px}.search-row input{border:0;outline:0;background:transparent;font-size:clamp(25px,4vw,48px);font-weight:300}.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:18px}.chips a,.chips button{border:1px solid var(--line);background:#fff;border-radius:999px;padding:7px 11px;font-size:10px}.toast{position:fixed;left:50%;bottom:26px;z-index:120;background:var(--ink);color:#fff;border-radius:999px;padding:11px 15px;font-size:11px;opacity:0;visibility:hidden;transform:translate(-50%,15px);transition:.2s}.toast.show{opacity:1;visibility:visible;transform:translate(-50%,0)}
/* home */.home-hero{padding:24px 0 50px}.hero-grid{display:grid;grid-template-columns:minmax(0,7fr) minmax(260px,3fr) minmax(220px,2fr);gap:18px}.lead{position:relative;min-height:550px;border-radius:var(--r);overflow:hidden;background:#ddd}.lead img{height:100%;object-fit:cover}.lead:after,.cover-card:after,.cat-lead:after,.video-card:after{content:'';position:absolute;inset:34% 0 0;background:linear-gradient(transparent,rgba(0,0,0,.84))}.lead-copy{position:absolute;left:30px;right:30px;bottom:26px;color:#fff;z-index:2}.lead-copy h1{font-size:clamp(35px,4.6vw,68px);font-weight:500;line-height:.98;letter-spacing:-.05em;margin:12px 0 13px;max-width:900px}.lead-copy p{max-width:700px;color:#e6e6e6;font-size:14px}.meta{display:flex;gap:10px;flex-wrap:wrap;font-size:10px;color:#aaa}.side-stack{display:grid;gap:18px}.side-card{background:#fff;border:1px solid var(--line);border-radius:var(--r);overflow:hidden}.side-card img{aspect-ratio:1.25;object-fit:cover}.side-body{padding:16px}.side-body h2{font-size:23px;font-weight:500;line-height:1.16;letter-spacing:-.03em;margin:8px 0}.color-card{min-height:220px;background:#ffd8ce;border-radius:var(--r);padding:20px;display:flex;flex-direction:column;justify-content:space-between}.color-card h3{font-size:25px;font-weight:500;line-height:1.15;letter-spacing:-.03em;margin:12px 0}.now{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:17px}.now-head{display:flex;justify-content:space-between;align-items:center;padding-bottom:13px;border-bottom:1px solid var(--line)}.now-head h2{font-size:16px;font-weight:500;margin:0}.now-item{display:grid;grid-template-columns:26px 1fr;gap:9px;padding:14px 0;border-bottom:1px solid var(--line)}.now-item:last-child{border-bottom:0}.now-item b{font-size:10px;color:var(--red)}.now-item h3{font-size:13px;font-weight:500;line-height:1.35;margin:0}.now-item span{display:block;font-size:9px;color:var(--muted);margin-top:5px}.section-head{display:flex;align-items:end;justify-content:space-between;gap:24px;margin-bottom:27px;padding-bottom:15px;border-bottom:1px solid var(--line)}.section-title{font-size:clamp(27px,3vw,41px);font-weight:500;letter-spacing:-.04em;line-height:1.08;margin:0}.section-note{max-width:520px;color:var(--muted);font-size:13px;margin:0}.text-link{display:inline-flex;align-items:center;gap:7px;font-size:12px;font-weight:500}.card-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:18px}.story-media{overflow:hidden;border-radius:14px;background:#ddd}.story-media img{aspect-ratio:1.32;object-fit:cover;transition:.3s}.story:hover img{transform:scale(1.025)}.story-body{padding:12px 2px 0}.story h3{font-size:19px;font-weight:500;line-height:1.28;letter-spacing:-.025em;margin:7px 0}.story p{font-size:12px;color:var(--muted)}.story small{font-size:9px;color:var(--muted)}.editorial{display:grid;grid-template-columns:minmax(0,1fr) 335px;gap:40px}.feed-item{display:grid;grid-template-columns:250px 1fr;gap:20px;padding:21px 0;border-top:1px solid var(--line)}.feed-item:first-child{padding-top:0;border-top:0}.feed-item img{aspect-ratio:1.45;object-fit:cover;border-radius:12px}.feed-item h3{font-size:24px;font-weight:500;line-height:1.19;letter-spacing:-.025em;margin:7px 0}.feed-item p{font-size:12px;color:var(--muted);margin:0 0 14px}.most{border-left:1px solid var(--line);padding-left:26px}.most h2{font-size:21px;font-weight:500;margin:0 0 12px}.most-row{display:grid;grid-template-columns:35px 1fr;gap:10px;padding:14px 0;border-top:1px solid var(--line)}.most-row b{font-size:22px;font-weight:300;color:#aaa}.most-row h3{font-size:13px;font-weight:500;line-height:1.35;margin:0}.dark{background:var(--night);color:#fff}.dark .section-head{border-color:rgba(255,255,255,.18)}.video-grid{display:grid;grid-template-columns:1.25fr .75fr .75fr;gap:18px}.video-card{position:relative;min-height:300px;border-radius:var(--r);overflow:hidden;background:#000}.video-card img{height:100%;object-fit:cover;opacity:.74}.video-copy{position:absolute;left:19px;right:19px;bottom:17px;color:#fff;z-index:2}.video-copy h3{font-size:21px;font-weight:500;line-height:1.2;margin:8px 0}.video-card.feature h3{font-size:32px}.play{width:41px;height:41px;border-radius:50%;background:#fff;color:#111;display:grid;place-items:center}
/* category */.cat-head{padding:42px 0 30px}.cat-title{display:grid;grid-template-columns:110px 1fr;gap:22px;align-items:end}.cat-code{border-top:2px solid var(--red);padding-top:10px;font-size:9px;color:var(--muted);letter-spacing:.12em}.cat-head h1{font-size:clamp(43px,6vw,82px);font-weight:500;line-height:.95;letter-spacing:-.055em;margin:0}.cat-head p{max-width:620px;font-size:14px;color:var(--muted)}.cat-feature{display:grid;grid-template-columns:1.35fr .65fr;gap:18px;padding-bottom:52px}.cat-lead{position:relative;min-height:490px;border-radius:var(--r);overflow:hidden}.cat-lead img{height:100%;object-fit:cover}.cat-copy{position:absolute;left:27px;right:27px;bottom:23px;color:#fff;z-index:2}.cat-copy h2{font-size:clamp(29px,3.5vw,52px);font-weight:500;line-height:1.04;letter-spacing:-.04em;margin:9px 0}.mini-list{display:grid;gap:18px}.mini{display:grid;grid-template-columns:42% 1fr;background:#fff;border:1px solid var(--line);border-radius:var(--r);overflow:hidden}.mini img{height:100%;object-fit:cover}.mini div{padding:17px}.mini h3{font-size:18px;font-weight:500;line-height:1.3;margin:7px 0}
/* article */.article-head{padding:44px 0 26px}.article-head-grid{display:grid;grid-template-columns:1fr 270px;gap:46px;align-items:end}.article-head h1{max-width:1040px;font-size:clamp(37px,5.2vw,70px);font-weight:500;line-height:1.01;letter-spacing:-.05em;margin:12px 0 17px}.article-deck{max-width:850px;font-size:16px;color:#5f5b57}.byline{border-top:1px solid var(--line);padding-top:14px;font-size:11px;color:var(--muted)}.article-actions{display:flex;flex-wrap:wrap;gap:7px;margin-top:18px}.article-actions button{height:37px;border:1px solid var(--line);background:#fff;border-radius:999px;padding:0 12px;font-size:10px}.article-hero{width:min(calc(100% - 48px),1640px);margin:auto;border-radius:20px;overflow:hidden}.article-hero img{aspect-ratio:4/5;object-fit:cover}.article-layout{width:min(calc(100% - 48px),1100px);margin:auto;display:grid;grid-template-columns:50px minmax(0,720px) 245px;gap:30px;padding:40px 0 72px}.share{position:sticky;top:145px;height:max-content;display:grid;gap:7px}.share button{width:40px;height:40px;border-radius:50%;border:1px solid var(--line);background:#fff}.article-body{font-size:16.5px;line-height:1.86;font-weight:300}.article-body p{margin:0 0 23px}.article-body h2{font-size:30px;font-weight:500;line-height:1.2;letter-spacing:-.025em;margin:42px 0 15px}.article-body h3{font-size:23px;font-weight:500;margin:34px 0 12px}.article-body blockquote{font-size:25px;font-weight:400;line-height:1.42;border-left:3px solid var(--red);padding-left:20px;margin:36px 0}.article-body figure{margin:32px 0}.article-body figure img{border-radius:14px}.article-body figcaption{font-size:10px;color:var(--muted);margin-top:7px}.article-note{position:sticky;top:145px;height:max-content;border-top:2px solid var(--ink);padding-top:13px}.article-note h3{font-size:15px;font-weight:500}.article-note p,.article-note li{font-size:11px;color:var(--muted)}
/* other */.simple-head{padding:52px 0}.simple-head h1{font-size:clamp(41px,6vw,74px);font-weight:500;line-height:1;letter-spacing:-.05em;margin:0 0 13px}.deck{max-width:650px;color:var(--muted);font-size:14px}.rank-item{display:grid;grid-template-columns:80px 280px 1fr;gap:22px;padding:27px 0;border-top:1px solid var(--line)}.rank-num{font-size:54px;font-weight:300;color:#aaa}.rank-item img{aspect-ratio:1.2;object-fit:cover;border-radius:13px}.rank-item h2{font-size:28px;font-weight:500;line-height:1.15;margin:0 0 9px}.vote{display:flex;gap:7px;margin-top:15px}.vote button{border:1px solid var(--line);background:#fff;border-radius:999px;padding:7px 11px;font-size:10px}.vote button.selected{background:var(--ink);color:#fff}.cover-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:18px}.cover-card{position:relative;min-height:510px;border-radius:var(--r);overflow:hidden}.cover-card img{height:100%;object-fit:cover}.cover-copy{position:absolute;left:21px;right:21px;bottom:19px;color:#fff;z-index:2}.cover-copy h2{font-size:28px;font-weight:500;line-height:1.12;margin:8px 0}.watch-feature{display:grid;grid-template-columns:1.25fr .75fr;gap:18px}.player{position:relative;aspect-ratio:16/9;border-radius:20px;overflow:hidden;background:#000}.player img{height:100%;object-fit:cover;opacity:.75}.big-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:68px;height:68px;border:0;border-radius:50%;background:#fff;font-size:24px}.panel{background:#fff;border:1px solid var(--line);border-radius:var(--r);padding:23px}.panel h2{font-size:23px;font-weight:500}.shop-hero{padding:38px 0 56px}.campaign{display:grid;grid-template-columns:1.25fr .75fr;gap:18px;background:#fff;border:1px solid var(--line);border-radius:20px;padding:18px}.campaign-media{min-height:510px;border-radius:14px;overflow:hidden}.campaign-media img{height:100%;object-fit:cover}.campaign-copy{padding:26px;display:flex;flex-direction:column;justify-content:space-between}.campaign-copy h1{font-size:clamp(39px,5vw,68px);font-weight:500;line-height:.99;letter-spacing:-.05em;margin:13px 0}.toolbar{display:flex;justify-content:space-between;gap:15px;align-items:center;margin:22px 0}.filter{display:flex;flex-wrap:wrap;gap:7px}.filter button,.select{height:37px;border:1px solid var(--line);background:#fff;border-radius:999px;padding:0 12px;font-size:10px}.product-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:23px 18px}.product{position:relative}.product-media{aspect-ratio:.86;border-radius:14px;overflow:hidden;background:#e6e3dc}.product-media img{height:100%;object-fit:cover;transition:.3s}.product:hover img{transform:scale(1.025)}.product h3{font-size:14px;font-weight:500;margin:10px 0 2px}.price{font-size:12px}.quick{position:absolute;left:10px;right:10px;bottom:10px;transform:translateY(160%);transition:.2s}.product:hover .quick{transform:none}.product-detail{display:grid;grid-template-columns:1.2fr .8fr;gap:38px;padding:40px 0 70px}.gallery{display:grid;grid-template-columns:1fr 1fr;gap:9px}.gallery img{aspect-ratio:.82;object-fit:cover;border-radius:13px}.product-info{position:sticky;top:145px;height:max-content}.product-info h1{font-size:36px;font-weight:500;line-height:1.1;letter-spacing:-.035em}.sizes{display:grid;grid-template-columns:repeat(4,1fr);gap:7px;margin:17px 0}.sizes button{height:40px;border:1px solid var(--line);background:#fff;border-radius:9px;font-size:10px}.sizes button.active{background:var(--ink);color:#fff}.accordion{border-top:1px solid var(--line);margin-top:24px}.accordion details{border-bottom:1px solid var(--line);padding:13px 0}.accordion summary{font-size:12px;font-weight:500}.accordion p{font-size:11px;color:var(--muted)}.form-card{width:min(100% - 30px,610px);margin:54px auto;background:#fff;border:1px solid var(--line);border-radius:18px;padding:30px}.form-card h1{font-size:35px;font-weight:500;letter-spacing:-.04em}.form-grid{display:grid;gap:14px}.field{display:grid;gap:6px}.field label{font-size:10px;font-weight:500;color:#555}.field input,.field textarea,.field select{min-height:44px;border:1px solid var(--line);border-radius:9px;background:#fff;padding:10px 12px;outline:0}.split{display:grid;grid-template-columns:1fr 1fr;gap:11px}.account-layout{display:grid;grid-template-columns:230px 1fr;gap:30px;padding:42px 0 68px}.account-nav{background:#fff;border:1px solid var(--line);border-radius:14px;padding:13px;height:max-content}.account-nav a{display:flex;gap:9px;padding:10px;border-radius:9px;font-size:12px}.account-nav a.active,.account-nav a:hover{background:var(--paper)}.cart-layout{display:grid;grid-template-columns:1fr 330px;gap:32px;padding:42px 0 68px}.cart-item{display:grid;grid-template-columns:125px 1fr auto;gap:17px;padding:17px 0;border-top:1px solid var(--line)}.cart-item img{aspect-ratio:.9;object-fit:cover;border-radius:11px}.summary{background:#fff;border:1px solid var(--line);border-radius:14px;padding:20px;height:max-content;position:sticky;top:145px}.summary-row{display:flex;justify-content:space-between;padding:9px 0;border-bottom:1px solid var(--line);font-size:12px}.summary-row.total{font-size:17px;font-weight:500;border-bottom:0}.search-result{display:grid;grid-template-columns:210px 1fr;gap:18px;padding:19px 0;border-top:1px solid var(--line)}.search-result img{aspect-ratio:1.45;object-fit:cover;border-radius:11px}.search-result h2{font-size:22px;font-weight:500;line-height:1.2;margin:7px 0}.prose{max-width:800px;font-size:15px;font-weight:300;line-height:1.86}.prose h2{font-size:27px;font-weight:500;margin:34px 0 11px}.directory{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}.directory a{background:#fff;border:1px solid var(--line);border-radius:13px;padding:16px}.directory h3{font-size:14px;font-weight:500;margin:0 0 7px}.directory p{font-size:10px;color:var(--muted);min-height:31px}.empty{min-height:55vh;display:grid;place-items:center;text-align:center}.empty h1{font-size:clamp(70px,14vw,175px);font-weight:300;color:#c9c5bd;line-height:.8;margin:0}.empty h2{font-size:28px;font-weight:500}.newsletter{background:var(--lime);padding:34px 0}.newsletter-grid{display:grid;grid-template-columns:1fr 1fr;gap:36px;align-items:center}.newsletter h2{font-size:32px;font-weight:500;line-height:1.1;letter-spacing:-.035em;margin:0}.newsletter-form{display:flex;gap:7px}.newsletter-form input{flex:1;min-width:0;border:0;border-radius:999px;padding:0 15px}.footer{background:#101114;color:#fff;padding:48px 0 22px}.footer-grid{display:grid;grid-template-columns:1.3fr repeat(3,1fr);gap:32px}.footer p{max-width:350px;color:#a8abb2;font-size:12px}.footer h3{font-size:10px;font-weight:500;color:#8d9097}.footer a:not(.brand){display:block;font-size:12px;margin:7px 0}.social{display:flex;gap:7px}.social a{width:34px;height:34px;border:1px solid rgba(255,255,255,.18);border-radius:50%;display:grid!important;place-items:center}.footer-bottom{margin-top:34px;padding-top:17px;border-top:1px solid rgba(255,255,255,.14);display:flex;justify-content:space-between;gap:16px;font-size:10px;color:#8d9097}
@media(max-width:1160px){.hero-grid{grid-template-columns:2fr 1fr}.now{grid-column:1/-1;display:grid;grid-template-columns:repeat(5,1fr)}.now-head{grid-column:1/-1}.now-item{border-bottom:0;border-right:1px solid var(--line);padding:13px 9px}.card-grid,.product-grid{grid-template-columns:repeat(3,1fr)}.video-grid{grid-template-columns:1.2fr 1fr}.video-card:last-child{grid-column:1/-1}.article-layout{grid-template-columns:48px 1fr}.article-note{display:none}.directory{grid-template-columns:repeat(3,1fr)}}@media(max-width:900px){.mainbar{grid-template-columns:1fr auto}.nav{display:none}.actions{grid-column:2}.hero-grid{grid-template-columns:1fr}.side-stack{grid-template-columns:1fr 1fr}.now{display:block}.now-item{border-right:0;border-bottom:1px solid var(--line)}.card-grid,.cover-grid{grid-template-columns:repeat(2,1fr)}.editorial{grid-template-columns:1fr}.most{border-left:0;border-top:1px solid var(--line);padding-left:0;padding-top:22px}.video-grid,.watch-feature,.cat-feature,.campaign{grid-template-columns:1fr}.video-card:last-child{grid-column:auto}.mini-list{grid-template-columns:1fr 1fr}.article-head-grid{grid-template-columns:1fr}.article-layout{grid-template-columns:1fr}.share{position:static;display:flex}.product-detail{grid-template-columns:1fr}.product-info{position:static}.account-layout,.cart-layout{grid-template-columns:1fr}.newsletter-grid,.footer-grid{grid-template-columns:1fr 1fr}.directory{grid-template-columns:repeat(2,1fr)}}@media(max-width:640px){.container{width:min(calc(100% - 28px),var(--max))}.utility,.topics{display:none}.mainbar{min-height:60px}.brand{font-size:24px}.hide-mobile{display:none}.home-hero{padding-top:14px}.lead{min-height:435px}.lead-copy{left:19px;right:19px;bottom:19px}.lead-copy p{display:none}.side-stack{grid-template-columns:1fr}.section{padding:48px 0}.section-head{align-items:start;flex-direction:column}.card-grid,.product-grid,.cover-grid{grid-template-columns:1fr 1fr;gap:19px 11px}.story h3{font-size:16px}.feed-item,.search-result{grid-template-columns:110px 1fr;gap:13px}.feed-item h3,.search-result h2{font-size:17px}.feed-item p{display:none}.cat-title{grid-template-columns:1fr}.cat-code{max-width:100px}.mini-list{grid-template-columns:1fr}.mini{grid-template-columns:38% 1fr}.article-hero{width:100%;border-radius:0}.article-hero img{aspect-ratio:4/5}.article-layout{width:min(calc(100% - 28px),1100px)}.article-body{font-size:15.5px}.rank-item{grid-template-columns:50px 1fr}.rank-item img{grid-column:2}.rank-num{font-size:40px}.campaign{padding:9px}.campaign-media{min-height:330px}.campaign-copy{padding:17px 9px 9px}.gallery{grid-template-columns:1fr}.split{grid-template-columns:1fr}.cart-item{grid-template-columns:88px 1fr}.cart-item>div:last-child{grid-column:2}.newsletter-grid,.footer-grid{grid-template-columns:1fr}.newsletter-form{flex-direction:column}.newsletter-form input{min-height:42px}.footer-bottom{flex-direction:column}.directory{grid-template-columns:1fr}}

/* v4 monochrome redesign */
.kicker{font-weight:500;font-size:10px;letter-spacing:.14em}.kicker:before{background:#111}
.badge{background:#111;color:#fff}
.btn.red,.btn{background:#111;border-color:#111;color:#fff}.btn.light{background:#fff;color:#111;border-color:#111}.btn.ghost{background:#fff;color:#111;border-color:#dcdcdc}
.site-header{position:sticky;top:0;z-index:50;background:#fff;border-bottom:1px solid #e8e8e8;backdrop-filter:none}
.topbar{min-height:70px;display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:18px}.header-left{display:flex;align-items:center;justify-content:flex-start}.header-right{display:flex;align-items:center;justify-content:flex-end;gap:4px}.brand{font-size:24px;font-weight:700;letter-spacing:-.04em}.brand-center{justify-self:center}.brand-mark{display:none}
.subnav{border-top:1px solid #efefef;border-bottom:1px solid #efefef;background:#fff}.subnav .container{min-height:44px;display:flex;align-items:center;justify-content:center}.nav{display:flex;justify-content:center;gap:28px;flex-wrap:nowrap;white-space:nowrap}.nav a{font-size:12px;font-weight:400;letter-spacing:.02em}.nav a:after{display:none}.nav a.active,.nav a:hover{font-weight:500}
.search-pill{height:42px;min-width:340px;max-width:340px;padding:0 16px;border:1px solid #dddddd;background:#fafafa;border-radius:6px;display:inline-flex;align-items:center;gap:10px;color:#8a8a8a;font-size:12px;cursor:pointer}.search-pill i{font-size:18px;color:#111}.search-button{width:40px;height:40px;border:0;background:transparent;border-radius:50%;display:grid;place-items:center;font-size:18px;cursor:pointer}.mobile-search{display:none}
.icon-btn{width:40px;height:40px;color:#111}.icon-btn:hover,.search-button:hover{background:#f5f5f5}.cart-icon sup{background:#111;color:#fff}
.topics,.utility{display:none!important}
.drawer{background:#fff}.drawer-nav a{font-size:20px}.drawer-foot{border-top:1px solid #eee}
.search-panel{background:#fff;border-bottom:1px solid #e9e9e9}.chips a,.chips button{background:#fff;border-color:#ddd}
body,.panel,.side-card,.now,.campaign,.form-card,.account-nav,.summary,.product-media,.drawer,.mini,.story-media,.cat-lead,.lead,.video-card,.cover-card{box-shadow:none}
.side-card,.now,.campaign,.panel,.form-card,.account-nav,.summary,.drawer,.mini{border-color:#ebebeb}
.color-card{background:#f7f7f7;border:1px solid #ebebeb}.dark{background:#fff;color:#111}.dark .section-head{border-color:#e5e5e5}.video-card img{opacity:.82}.video-copy,.cover-copy,.cat-copy,.lead-copy{color:#fff}
.newsletter{background:#fff;border-top:1px solid #ebebeb;border-bottom:1px solid #ebebeb}.newsletter h2{font-size:30px}.newsletter-form input{border:1px solid #ddd;min-height:44px}.footer{background:#111;color:#fff}.footer p,.footer-bottom,.footer h3{color:#a5a5a5}.footer a:not(.brand){color:#fff}
.section-title,.story h3,.feed-item h3,.cover-copy h2,.article-head h1,.cat-head h1,.campaign-copy h1,.product-info h1,.simple-head h1{font-weight:500}.section-title{font-size:clamp(26px,3vw,38px)}.feed-item h3{font-size:22px}.lead-copy h1{font-size:clamp(34px,4.2vw,58px)}.story h3{font-size:18px}.side-body h2{font-size:21px}.article-body blockquote{border-left-color:#111}
.mainbar{display:none}
@media(max-width:900px){.topbar{grid-template-columns:auto 1fr auto}.brand-center{justify-self:center}.search-pill{display:none}.mobile-search{display:grid}.subnav .container{overflow:auto;justify-content:flex-start}.nav{gap:22px;padding:0 0 0 2px}}
@media(max-width:640px){.topbar{min-height:60px}.brand{font-size:22px}.subnav .container{min-height:40px}.nav a{font-size:11px}.hide-mobile{display:none}.mobile-search{display:grid}}

/* v4 fix */
.nav{display:flex!important}
@media(max-width:900px){.nav{display:flex!important}}


/* v5 refinement */
:root{--ink:#101010;--muted:#707070;--paper:#fff;--card:#fff;--line:#e8e8e8;--red:#101010;--lime:#fff;--night:#fff;--r:14px;--max:1440px}
html{font-size:16px}
body{background:#fff;color:#101010}
a{transition:all .18s ease}
.container{width:min(calc(100% - 56px),var(--max))}
.site-header{box-shadow:0 1px 0 rgba(0,0,0,.04)}
.topbar{min-height:76px;gap:24px}
.brand{font-size:30px;font-weight:700;letter-spacing:-.045em;line-height:1}
.search-pill{min-width:380px;max-width:380px;height:44px;border-radius:8px;background:#fafafa;border:1px solid #e2e2e2;color:#8c8c8c}
.search-pill:hover{background:#f5f5f5;border-color:#d5d5d5}
.subnav{border-top:1px solid #f1f1f1;border-bottom:1px solid #ebebeb}
.subnav .container{min-height:46px}
.nav{gap:32px}
.nav a{font-size:12.5px;letter-spacing:.03em;color:#202020}.nav a.active,.nav a:hover{color:#000}
.icon-btn,.search-button{border-radius:8px}
.icon-btn:hover,.search-button:hover{background:#f5f5f5}
.drawer{border-right:1px solid #ebebeb}
.search-panel{box-shadow:0 18px 40px rgba(0,0,0,.06)}
.search-row input{font-size:clamp(24px,3vw,40px)}
.badge{padding:7px 12px;border-radius:999px;font-size:9px;letter-spacing:.12em}
.home-hero{padding:30px 0 68px}
.hero-grid{grid-template-columns:minmax(0,1.65fr) minmax(320px,.9fr) minmax(280px,.65fr);gap:22px}
.lead,.side-card,.now,.campaign,.panel,.form-card,.account-nav,.summary,.product-media,.mini,.cover-card,.video-card,.cat-lead{border-radius:18px}
.lead{min-height:640px;background:#ececec}
.lead:after,.cover-card:after,.cat-lead:after,.video-card:after{inset:38% 0 0;background:linear-gradient(180deg,transparent 0%,rgba(0,0,0,.10) 24%,rgba(0,0,0,.82) 100%)}
.lead-copy{left:34px;right:34px;bottom:32px}
.lead-copy h1{max-width:860px;font-size:clamp(40px,4.5vw,64px);font-weight:500;line-height:.96;letter-spacing:-.05em;margin:14px 0 15px}
.lead-copy p{max-width:620px;font-size:14px;line-height:1.6;color:#ededed}
.meta{font-size:10px;color:#cfcfcf}
.side-stack{gap:22px}
.side-card{border:1px solid #ededed;overflow:hidden;background:#fff}
.side-card img{aspect-ratio:1.18}
.side-body{padding:18px}
.side-body h2{font-size:24px;line-height:1.15;margin:8px 0 0}
.color-card{min-height:236px;border-radius:18px;background:#f7f7f7;border:1px solid #ededed;padding:22px}
.color-card h3{font-size:26px;line-height:1.12;margin:12px 0 0}
.now{padding:18px 18px 8px;border:1px solid #ededed;background:#fff}
.now-head h2{font-size:18px;letter-spacing:-.02em}
.now-item{padding:15px 0 16px}.now-item h3{font-size:13px;line-height:1.42}
.section{padding:82px 0}.compact{padding:54px 0}
.section-head{margin-bottom:30px;padding-bottom:18px;border-bottom:1px solid #ececec}
.section-title{font-size:clamp(28px,3.1vw,42px);font-weight:500;letter-spacing:-.045em;line-height:1.05}
.section-note{font-size:13px;line-height:1.7;color:#6e6e6e}
.card-grid{gap:24px;align-items:start}.story{position:relative}.story-media{border-radius:16px;background:#eee}.story-media img{aspect-ratio:1.18;object-fit:cover}
.story-body{padding-top:14px}.story h3{font-size:20px;line-height:1.28;letter-spacing:-.025em;margin:8px 0 7px}.story small{font-size:10px}
.editorial{grid-template-columns:minmax(0,1fr) 360px;gap:48px}
.feed-item{grid-template-columns:270px 1fr;gap:22px;padding:24px 0;border-top:1px solid #ededed}.feed-item img{border-radius:16px}
.feed-item h3{font-size:26px;line-height:1.18;letter-spacing:-.03em;margin:8px 0}.feed-item p{font-size:13px;line-height:1.68;color:#6d6d6d;margin-bottom:16px}
.most{border-left:0;padding:0;background:#fafafa;border:1px solid #ededed;border-radius:18px;padding:20px}
.most h2{font-size:22px;margin:0 0 8px}.most-row{grid-template-columns:38px 1fr;padding:16px 0;border-top:1px solid #e7e7e7}.most-row:first-of-type{border-top:0}.most-row b{font-size:26px;color:#b1b1b1}.most-row h3{font-size:14px;line-height:1.42}
.dark{background:#fff}.video-grid{gap:22px}.video-card{min-height:320px}.video-card.feature{min-height:460px}.video-copy{left:22px;right:22px;bottom:20px}.video-copy h3{font-size:22px;line-height:1.18;margin-top:10px}.video-card.feature h3{font-size:34px}.play{width:44px;height:44px}
.product-grid{gap:28px 20px}.product-media{background:#f1f1f1;border-radius:16px}.product h3{font-size:15px;margin-top:12px}.price{font-size:12px;color:#525252}.quick{left:12px;right:12px;bottom:12px}
.cat-head{padding:50px 0 34px}.cat-head h1{font-size:clamp(48px,6vw,88px);letter-spacing:-.06em}.cat-head p{font-size:14px;line-height:1.72}
.cat-feature{gap:22px;padding-bottom:56px}.cat-lead{min-height:520px}.cat-copy h2{font-size:clamp(30px,3.6vw,54px)}
.article-head h1{font-size:clamp(36px,4vw,60px);font-weight:500;line-height:1.02}.article-body{font-size:17px;line-height:1.92;color:#1d1d1d}.article-layout{gap:36px}.share a{border-color:#e5e5e5;background:#fff}
.player,.campaign-media{border-radius:18px}.campaign{padding:22px}.campaign-copy{padding:30px}.campaign-copy h1{font-size:clamp(42px,4.4vw,70px);line-height:.98}
.toolbar{margin:24px 0}.filter button,.select{height:39px;border-radius:999px}
.form-card{padding:34px 34px 30px}.field input,.field textarea,.field select{border-color:#dfdfdf}
.newsletter{padding:42px 0;background:#fcfcfc;border-top:1px solid #ececec;border-bottom:1px solid #ececec}.newsletter-grid{gap:42px}.newsletter h2{font-size:34px;letter-spacing:-.04em;line-height:1.08}.newsletter-form{gap:10px}.newsletter-form input{padding:0 18px;border-radius:999px;background:#fff}.newsletter .btn{min-width:180px}
.footer{padding:56px 0 24px;background:#101010}.footer-grid{gap:34px}.footer .brand{font-size:28px}.footer p{font-size:12.5px;line-height:1.7}.footer a:not(.brand){font-size:12.5px}.social a{width:36px;height:36px}
/* categories/listing/shared cards */
.mini,.directory a,.account-nav,.summary,.panel,.form-card,.campaign,.product-info .accordion details{border-color:#ececec}
.directory{gap:16px}.directory a{border-radius:16px}.directory h3{font-size:15px}
.empty h2{font-size:30px}
@media(max-width:1180px){.hero-grid{grid-template-columns:1fr 1fr}.now{grid-column:1/-1}.editorial{grid-template-columns:1fr}.most{margin-top:8px}.product-grid{grid-template-columns:repeat(3,1fr)}}
@media(max-width:900px){.container{width:min(calc(100% - 36px),var(--max))}.topbar{grid-template-columns:auto 1fr auto;min-height:68px}.brand{font-size:26px}.search-pill{display:none}.mobile-search{display:grid}.subnav .container{justify-content:flex-start;overflow:auto}.nav{gap:24px;padding-right:10px}.hero-grid,.watch-feature,.campaign,.cat-feature,.editorial,.product-detail,.account-layout,.cart-layout{grid-template-columns:1fr}.side-stack{grid-template-columns:1fr 1fr}.lead{min-height:560px}.section{padding:64px 0}.card-grid,.cover-grid,.product-grid{grid-template-columns:repeat(2,1fr)}.feed-item{grid-template-columns:220px 1fr}}
@media(max-width:640px){.container{width:min(calc(100% - 24px),var(--max))}.topbar{min-height:60px;gap:12px}.brand{font-size:24px}.subnav .container{min-height:40px}.nav{gap:18px}.nav a{font-size:11px}.home-hero{padding:14px 0 48px}.hero-grid{gap:16px}.lead{min-height:430px;border-radius:14px}.lead-copy{left:18px;right:18px;bottom:18px}.lead-copy h1{font-size:32px}.lead-copy p{display:none}.side-stack{grid-template-columns:1fr}.section{padding:50px 0}.compact{padding:42px 0}.section-title{font-size:28px}.card-grid,.cover-grid,.product-grid{grid-template-columns:1fr}.feed-item{grid-template-columns:110px 1fr;gap:14px}.feed-item h3{font-size:18px}.feed-item p{display:none}.most{padding:16px}.video-card.feature{min-height:300px}.video-card.feature h3{font-size:26px}.newsletter{padding:34px 0}.newsletter h2{font-size:28px}.newsletter-form{flex-direction:column}.newsletter .btn{width:100%}.footer{padding-top:44px}}


/* v7 hero slider and true dropdown mega menu */
.subnav{position:relative;z-index:20}
.nav a.active{font-weight:600}
.mega-menu{position:fixed;left:0;right:0;top:132px;z-index:70;background:#fff;border-top:1px solid #ececec;border-bottom:1px solid #e7e7e7;box-shadow:0 18px 50px rgba(0,0,0,.08);opacity:0;visibility:hidden;pointer-events:none;transform:translateY(-14px);transition:opacity .26s ease,transform .32s cubic-bezier(.22,.61,.36,1),visibility .26s ease;will-change:transform,opacity}
.mega-menu.active{opacity:1;visibility:visible;pointer-events:auto;transform:translateY(0)}
.mega-menu .container{padding-top:0;padding-bottom:0}
.mega-panel{display:none;padding:24px 0 30px}
.mega-panel.active{display:block}
.mega-head{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;margin-bottom:14px}
.mega-head h3{margin:0;font-size:34px;line-height:1;letter-spacing:-.04em;font-weight:500}
.mega-head p{margin:6px 0 0;font-size:13px;color:#707070}
.mega-actions{display:flex;align-items:center;gap:16px}
.mega-controls{display:flex;gap:8px}
.mega-arrow{width:36px;height:36px;border-radius:999px;border:1px solid #dcdcdc;background:#fff;display:grid;place-items:center;cursor:pointer}
.mega-arrow:hover{background:#f6f6f6}
.mega-track{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(220px,1fr);gap:14px;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;padding-bottom:6px}
.mega-track::-webkit-scrollbar{display:none}
.mega-card{display:block;min-width:0;color:#111}
.mega-card img{width:100%;aspect-ratio:4/5;object-fit:cover;border-radius:8px;background:#eee}
.mega-card-copy{padding-top:8px}.mega-card h3{font-size:15px;line-height:1.35;font-weight:500;margin:6px 0 0}
.hero-slider{position:relative;min-height:760px;background:#111;color:#fff;overflow:hidden}
.hero-slide{position:absolute;inset:0;opacity:0;pointer-events:none;transition:opacity .45s ease}.hero-slide.active{opacity:1;pointer-events:auto}
.hero-slide img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}.hero-overlay{position:absolute;inset:0;background:linear-gradient(180deg,rgba(0,0,0,.15) 0%,rgba(0,0,0,.22) 35%,rgba(0,0,0,.72) 100%)}
.hero-copy{position:relative;z-index:2;display:flex;flex-direction:column;justify-content:flex-end;min-height:760px;padding:0 0 120px}
.kicker.light{color:#fff}.kicker.light:before{background:#fff}
.hero-copy h1{max-width:760px;font-size:clamp(44px,5vw,68px);line-height:.96;letter-spacing:-.055em;margin:14px 0 14px;color:#fff;font-weight:500}
.hero-copy p{max-width:640px;color:#e7e7e7;font-size:16px;line-height:1.6;margin-bottom:26px}
.hero-ui{position:absolute;left:0;right:0;bottom:38px;z-index:4;display:flex;justify-content:space-between;align-items:center}
.hero-dots{display:flex;gap:8px;justify-content:center;align-items:center}.hero-dots button{width:8px;height:8px;border-radius:999px;border:0;background:rgba(255,255,255,.45);padding:0;cursor:pointer}.hero-dots button.active{width:10px;height:10px;background:#fff}
.hero-nav{display:flex;gap:10px}.hero-control{width:42px;height:42px;border-radius:2px;border:1px solid rgba(255,255,255,.38);background:rgba(0,0,0,.18);color:#fff;display:grid;place-items:center;cursor:pointer}.hero-control:hover{background:rgba(255,255,255,.1)}
@media(max-width:1024px){.mega-menu{top:124px}.mega-head{align-items:flex-start;flex-direction:column}.mega-actions{width:100%;justify-content:space-between}.mega-track{grid-auto-columns:minmax(200px,260px)}.hero-slider,.hero-copy{min-height:640px}.hero-copy{padding-bottom:100px}.hero-copy h1{max-width:680px}}
@media(max-width:768px){.mega-menu{display:none!important}.hero-slider,.hero-copy{min-height:520px}.hero-copy{padding-bottom:90px}.hero-copy h1{font-size:36px;max-width:100%}.hero-copy p{font-size:14px;max-width:100%}.hero-ui{bottom:20px}.hero-control{width:38px;height:38px}}

/* v8 — category archive pagination (Phase 2, no mockup equivalent) */
.pagination{display:flex;gap:8px;justify-content:center;margin-top:40px}
.pagination a{width:38px;height:38px;display:grid;place-items:center;border:1px solid var(--line);border-radius:999px;color:var(--ink);text-decoration:none;font-size:13px}
.pagination a:hover{background:#f6f6f6}
.pagination a.active{background:var(--ink);color:#fff;border-color:var(--ink)}
@media(max-width:640px){.hero-slider,.hero-copy{min-height:480px}.hero-copy{padding-bottom:84px}.hero-copy h1{font-size:32px;line-height:1}.hero-copy p{display:block}.hero-nav{gap:8px}}

/* v9 — /search inline search box (Phase 4, no mockup equivalent — search.html
   only has the header overlay's #globalSearch, not an on-page box) */
.search-inline-form{display:flex;align-items:center;gap:12px;max-width:640px;margin-top:22px;padding:12px 18px;border:1px solid var(--line);border-radius:999px;background:var(--soft)}
.search-inline-form i{color:var(--muted)}
.search-inline-form input{flex:1;border:0;background:transparent;outline:none;font-family:inherit;font-size:15px;color:var(--ink)}
.search-inline-form input::placeholder{color:var(--muted)}
@media(max-width:640px){.search-inline-form{padding:10px 14px}.search-inline-form .btn{padding:10px 16px;font-size:12px}}

/* v10 — account area (Phase 4): login/register/OTP/forgot/LINE-link cards +
   /account dashboard shell. None of this existed in style.css before — the
   whole account section was rendering unstyled since the Phase 0 CSS swap
   (it used STRTWR-only tokens/classes that never made it into the demo's
   style.css). Visual language matches the existing .form-card exactly
   (same width/radius/border/padding) since that's the site's one real
   "centered form" precedent (login.html in the demo). */
.auth-wrap{width:min(100% - 30px,540px);margin:54px auto}
.auth-card{background:#fff;border:1px solid var(--line);border-radius:18px;padding:34px 34px 30px}
.auth-header{text-align:center;margin-bottom:22px}
.auth-icon{width:52px;height:52px;margin:0 auto 14px;border-radius:14px;background:var(--ink);color:#fff;display:flex;align-items:center;justify-content:center;font-size:22px}
.auth-title{font-size:26px;font-weight:500;letter-spacing:-.03em;margin:0 0 6px}
.auth-subtitle{font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin-bottom:10px}
.auth-intro{font-size:13px;color:var(--muted);line-height:1.6;margin:0}
.auth-stepper{display:flex;align-items:center;gap:8px;margin-bottom:24px;font-size:11px;color:var(--muted)}
.auth-step{display:flex;align-items:center;gap:6px;white-space:nowrap}
.auth-step.current{color:var(--ink);font-weight:600}
.auth-step.done{color:var(--success)}
.auth-step-sep{flex:1;height:1px;background:var(--line);min-width:12px}
.auth-step-sep.done{background:var(--success)}
.auth-form{display:grid;gap:16px}
.auth-field label{display:block;font-size:11.5px;font-weight:500;color:var(--ink);margin-bottom:7px}
.auth-field .req{color:var(--danger)}
.auth-field input,.auth-field select,.auth-field textarea{width:100%;min-height:46px;padding:0 14px;border:1px solid var(--line);border-radius:9px;background:#fff;font-family:inherit;font-size:14px;color:var(--ink);outline:0}
.auth-field input:focus{border-color:var(--ink)}
.auth-field input:disabled{background:var(--soft);color:var(--muted)}
.auth-field-input-wrap{position:relative}
.auth-field-input-wrap input{padding-left:38px}
.auth-field-input-wrap .field-icon{position:absolute;left:13px;top:50%;transform:translateY(-50%);color:var(--muted);font-size:14px}
.auth-hint{font-size:11px;color:var(--muted);margin-top:6px;line-height:1.5}
.auth-btn{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;min-height:46px;padding:0 18px;border:1px solid var(--ink);border-radius:999px;background:var(--ink);color:#fff;font-family:inherit;font-size:13px;font-weight:500;cursor:pointer}
.auth-btn:hover{opacity:.9}
.auth-btn-sc{background:#fff;color:var(--ink);border-color:var(--line)}
.auth-footer{text-align:center;margin-top:20px;font-size:12.5px;color:var(--muted)}
.auth-footer a{color:var(--ink);font-weight:500}
.otp-boxes{display:flex;gap:8px;justify-content:center}
.otp-box{width:44px;height:52px;text-align:center;font-size:20px;padding:0!important}
@media(max-width:520px){.auth-card{padding:26px 20px 22px}.otp-box{width:38px;height:48px;font-size:17px}}

/* /account dashboard shell — tabs partial + section cards + quick actions */
.account-wrap{max-width:1000px;margin:0 auto;padding:0 20px 60px}
.account-section{background:#fff;border:1px solid var(--line);border-radius:16px;padding:22px 24px;margin-bottom:18px}
.account-section-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px;flex-wrap:wrap}
.account-section-head h2{font-size:16px;font-weight:500;margin:0}
.account-cta{font-size:12.5px;font-weight:500;color:var(--ink);white-space:nowrap}
.account-empty{text-align:center;padding:50px 20px;color:var(--muted)}
.account-empty i{font-size:36px;opacity:.4}
.account-empty .msg{font-size:15px;font-weight:500;color:var(--ink);margin:12px 0 4px}
.account-empty .sub{font-size:12.5px;margin-bottom:16px}
.account-btn{display:inline-flex;align-items:center;gap:6px;padding:10px 18px;border-radius:999px;background:var(--ink);color:#fff;font-size:12.5px;font-weight:500;text-decoration:none}
.account-quickactions{display:grid;gap:2px}
.account-quickaction{display:flex;align-items:center;gap:14px;padding:14px 6px;text-decoration:none;color:inherit;border-bottom:1px solid var(--line)}
.account-quickaction:last-child{border-bottom:0}
.account-quickaction>i:first-child{font-size:18px;color:var(--muted);width:22px;text-align:center}
.account-quickaction .hd{font-size:13.5px;font-weight:500;color:var(--ink)}
.account-quickaction .sub{font-size:11.5px;color:var(--muted);margin-top:2px}
.account-quickaction .arr{margin-left:auto;color:var(--muted)}
.account-quickaction.danger .hd{color:var(--danger)}
.account-nav{display:flex;flex-direction:column;gap:2px}
.account-nav a{display:flex;align-items:center;gap:10px;padding:11px 14px;border-radius:9px;color:var(--muted);text-decoration:none;font-size:13px}
.account-nav a.active,.account-nav a.is-active{background:var(--ink);color:#fff}

/* v-tokenfix — dark sub-brand token set converted to the STRTWR monochrome
   theme. ~98 ticketing/commerce views (events, tickets, donate, slip_upload,
   sponsor, advertise, promote, casting, radio, rappers, admin banners/orders/
   etc.) reference these tokens via var(--c1) etc. — none of these names
   collide with the STRTWR monochrome tokens above, so this is additive only.
   Mapping matches the one already proven in public/install/index.php's own
   :root (bg/c1/c2/c3/bd/tx/mu/gn/rd2 → monochrome) — this :root block is now
   the shared source of truth for the rest of the app.
   --rbr/--rdk/--rgw (the old ROII brand red + its glow) now resolve to ink —
   no accent red anywhere per the monochrome design token rule.
   --gn/--rd2/--yl/--bl/--lv were a second, brighter status-color set (for use
   on dark surfaces); desaturated to line up with --success/--warning/--danger.
   Also adds --success/--warning/--danger/--soft: defined in admin.css but public
   store/account views (cart, checkout, order status, lookup) load only this file. */
:root{
  --bg:#fff;--c1:#fff;--c2:#f7f7f7;--c3:#f0f0f0;
  --bd:#e8e8e8;--bd2:#dcdcdc;--tx:#101010;--mu:#707070;--mu2:#9a9a9a;
  --rbr:#101010;--rdk:#000;--rgw:rgba(16,16,16,.16);
  --gn:#277a46;--rd2:#a83b36;--yl:#9b6417;--bl:#2f5f8f;--lv:#5b4b8a;
  --success:#277a46;--warning:#9b6417;--danger:#a83b36;--soft:#f7f7f7;
}

/* v-stickyfooter — footer must stay pinned to the bottom of the viewport on
   short pages (empty states, thin content before DB has data, etc.); on tall
   pages <main> already exceeds the flex space so scrolling works as normal. */
body{display:flex;flex-direction:column;min-height:100vh}
main{flex:1 0 auto}

/* v-authpolish — login/forgot/register auth-field labels were missing the
   icon gap that edit_profile.php and change_password.php already use
   (inline margin-right:4px on the <i>) — icon ran straight into the label
   text ("✉อีเมล / Username"). One shared rule instead of patching every
   view's inline style. Also gives .auth-icon a touch of depth so the flat
   black square doesn't sit dead-flat against the card. */
.auth-field label i{margin-right:4px}
.auth-icon{box-shadow:0 8px 20px rgba(16,16,16,.22)}

/* v-socialicons — footer .social a inherits font-size:12px + margin:7px 0
   from the generic ".footer a:not(.brand)" rule; the icon glyph was
   rendering small and the leftover margin nudged the box off the circle's
   true center. display:grid + place-items:center already centers the icon
   box correctly — this just resets the inherited margin and gives the
   glyph a bit more size so it reads as centered. */
.social a{margin:0;font-size:15px;line-height:1}

/* v-motion — Motion Kit (React Bits–inspired effects, ported to vanilla CSS/JS).
   Engine lives in js/common.js so BOTH layouts get it (admin.php deliberately
   does not load app.js). Everything here is opt-in via data-* attributes; the
   engine auto-tags a small allow-list of existing classes (.story, .card-grid
   children, .section-head, .metric, .quick-action, .panel) so no view file has
   to change to get scroll reveals.

   Ported from: FadeContent + AnimatedContent + ScrollFloat + BlurText (reveal),
   CountUp + Counter (countup), ShinyText (shiny), SpotlightCard (spotlight),
   GlareHover (glare), StarBorder (starborder), Magnet (magnet),
   ClickSpark (spark), ScrollVelocity (marquee), DecryptedText (scramble).

   No new !important — this layer is last in the file, so plain selectors win.
   Every effect is disabled under prefers-reduced-motion at the bottom. */

/* --- reveal: FadeContent / AnimatedContent / ScrollFloat / BlurText --- */
[data-reveal]{
  opacity:0;
  transform:translateY(20px);
  transition:opacity .72s cubic-bezier(.22,.61,.36,1),
             transform .72s cubic-bezier(.22,.61,.36,1),
             filter .72s cubic-bezier(.22,.61,.36,1);
  transition-delay:var(--reveal-delay,0ms);
  will-change:opacity,transform;
}
[data-reveal="down"]{transform:translateY(-20px)}
[data-reveal="left"]{transform:translateX(-26px)}
[data-reveal="right"]{transform:translateX(26px)}
[data-reveal="scale"]{transform:scale(.965)}
[data-reveal="blur"]{transform:translateY(12px);filter:blur(9px)}
[data-reveal="fade"]{transform:none}
[data-reveal].revealed{opacity:1;transform:none;filter:none}
/* reveal finished — drop the compositor hint so long pages don't hold layers */
[data-reveal].reveal-done{will-change:auto;transition-delay:0ms}

/* SplitText / BlurText per-word — engine splits the node into .rv-w spans.
   Uses animation, not transition: these headings usually sit above the fold,
   and a transition needs a painted start frame to animate from — which the
   reveal observer can only give it by leaving the text invisible for a frame
   (a visible flash). An animation starts from its own 0% keyframe the moment
   the span is created, so it plays on page load with nothing to flash. */
[data-split-text]{opacity:1;transform:none;filter:none}
[data-split-text] .rv-w{
  display:inline-block;
  opacity:0;
  animation:stw-word .62s cubic-bezier(.22,.61,.36,1) forwards;
  animation-delay:var(--w-delay,0ms);
}
@keyframes stw-word{
  from{opacity:0;transform:translateY(.5em);filter:blur(7px)}
  to{opacity:1;transform:none;filter:none}
}
/* below-the-fold headings wait for the reveal observer instead */
[data-split-text][data-split-defer] .rv-w{animation-play-state:paused}
[data-split-text][data-split-defer].revealed .rv-w{animation-play-state:running}

/* --- countup: CountUp / Counter --- */
[data-countup],[data-cart-count]{font-variant-numeric:tabular-nums}
[data-cart-count].count-bump{animation:stw-bump .34s cubic-bezier(.34,1.56,.64,1)}
@keyframes stw-bump{0%{transform:scale(1)}45%{transform:scale(1.42)}100%{transform:scale(1)}}

/* --- shiny: ShinyText — monochrome sweep, no new colour token needed --- */
[data-shiny]{
  background:linear-gradient(100deg,var(--ink) 42%,rgba(16,16,16,.28) 50%,var(--ink) 58%);
  background-size:230% 100%;
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  animation:stw-shine 3.6s linear infinite;
}
/* on dark/inverted surfaces (hero overlay, .kicker.light) */
[data-shiny="light"]{
  background:linear-gradient(100deg,#fff 42%,rgba(255,255,255,.34) 50%,#fff 58%);
  background-size:230% 100%;
  -webkit-background-clip:text;background-clip:text;
}
@keyframes stw-shine{0%{background-position:230% 0}100%{background-position:-130% 0}}

/* --- spotlight: SpotlightCard — cursor-following radial wash --- */
[data-spotlight]{position:relative}
[data-spotlight]::after{
  content:"";position:absolute;inset:0;border-radius:inherit;
  pointer-events:none;opacity:0;transition:opacity .38s ease;
  background:radial-gradient(210px circle at var(--sx,50%) var(--sy,50%),
             rgba(16,16,16,.085),rgba(16,16,16,0) 64%);
}
[data-spotlight].spot-on::after{opacity:1}

/* --- glare: GlareHover — light sweeping across media/thumbnails --- */
[data-glare]{position:relative;overflow:hidden}
[data-glare]::before{
  content:"";position:absolute;top:-10%;left:-130%;
  width:62%;height:120%;z-index:2;pointer-events:none;
  background:linear-gradient(100deg,transparent,rgba(255,255,255,.44),transparent);
  transform:skewX(-18deg);
  transition:left .72s cubic-bezier(.22,.61,.36,1);
}
[data-glare]:hover::before,[data-glare]:focus-within::before{left:140%}

/* --- starborder: StarBorder — travelling border light for CTAs.
   Paused while idle: a conic-gradient rotation repaints every frame, and the
   newsletter CTA that carries this sits on EVERY public page. It spins on
   hover/focus, or always with data-starborder="always". --- */
[data-starborder]{position:relative;isolation:isolate;overflow:hidden}
[data-starborder]::before{
  content:"";position:absolute;z-index:-1;inset:-140%;
  background:conic-gradient(from 0deg,transparent 0 72%,rgba(16,16,16,.55) 84%,transparent 92%);
  animation:stw-spin 3.8s linear infinite;
  animation-play-state:paused;
}
[data-starborder]:hover::before,
[data-starborder]:focus-visible::before,
[data-starborder="always"]::before{animation-play-state:running}
[data-starborder]::after{
  content:"";position:absolute;z-index:-1;inset:1px;border-radius:inherit;
  background:var(--paper,#fff);
}
[data-starborder="light"]::before{
  background:conic-gradient(from 0deg,transparent 0 72%,rgba(255,255,255,.7) 84%,transparent 92%);
}
[data-starborder="light"]::after{background:var(--ink,#101010)}
@keyframes stw-spin{to{transform:rotate(1turn)}}

/* --- magnet: Magnet — engine writes --mx/--my, CSS only smooths it --- */
[data-magnet]{
  display:inline-block;
  transform:translate(var(--mx,0px),var(--my,0px));
  transition:transform .28s cubic-bezier(.22,.61,.36,1);
}
[data-magnet].magnet-active{transition:transform .08s linear}

/* --- spark: ClickSpark — 8 rays fired from the click point --- */
.stw-spark{position:fixed;left:0;top:0;z-index:9998;pointer-events:none;width:0;height:0}
.stw-spark i{
  position:absolute;left:0;top:0;
  width:12px;height:1.5px;border-radius:2px;
  background:var(--ink,#101010);
  transform-origin:0 50%;
  animation:stw-ray .46s cubic-bezier(.22,.61,.36,1) forwards;
}
@keyframes stw-ray{
  0%{opacity:.85;transform:rotate(var(--ray)) translateX(3px) scaleX(.5)}
  100%{opacity:0;transform:rotate(var(--ray)) translateX(26px) scaleX(.12)}
}

/* --- marquee: ScrollVelocity — infinite editorial ticker --- */
[data-marquee]{overflow:hidden;white-space:nowrap;display:flex}
[data-marquee] .mq-run{
  display:inline-flex;flex:0 0 auto;gap:var(--mq-gap,42px);padding-right:var(--mq-gap,42px);
  animation:stw-marquee var(--mq-dur,26s) linear infinite;
  will-change:transform;
}
[data-marquee="right"] .mq-run{animation-direction:reverse}
[data-marquee]:hover .mq-run{animation-play-state:paused}
@keyframes stw-marquee{to{transform:translateX(-100%)}}

/* --- scramble: DecryptedText / ScrambledText — engine swaps textContent --- */
[data-scramble]{font-variant-ligatures:none}
[data-scramble].scrambling{opacity:.92}

/* --- reduced motion: every effect above collapses to its final state.
   Same specificity as the rules above but declared later, so no !important. */
@media (prefers-reduced-motion:reduce){
  [data-reveal],[data-reveal].revealed{
    opacity:1;transform:none;filter:none;transition:none;will-change:auto;
  }
  [data-split-text] .rv-w,[data-split-text].revealed .rv-w,
  [data-split-text][data-split-defer] .rv-w{
    opacity:1;transform:none;filter:none;animation:none;
  }
  [data-shiny],[data-shiny="light"]{
    animation:none;background:none;color:inherit;-webkit-text-fill-color:currentColor;
  }
  [data-spotlight]::after,[data-spotlight].spot-on::after{opacity:0;transition:none}
  [data-glare]::before,[data-glare]:hover::before{display:none}
  [data-starborder]::before{animation:none}
  [data-magnet],[data-magnet].magnet-active{transform:none;transition:none}
  [data-cart-count].count-bump{animation:none}
  [data-marquee] .mq-run{animation:none}
  .stw-spark{display:none}
}

/* v-motion-b — Motion Kit part 2 (ScrollStack · StaggeredMenu · TiltedCard).
   Same rules as the v-motion layer above: engine in js/common.js, data-* driven,
   no new !important, everything collapses under prefers-reduced-motion.

   Ported from: ScrollStack (data-scrollstack), StaggeredMenu (drawer nav,
   CSS-only — no partial edit needed), TiltedCard (data-tilt). */

/* --- scrollstack: ScrollStack — cards pin and shrink as the next one rides up.
   --ss-top is written at runtime from .site-header height (same approach as
   app.js syncMegaOffset) so it never goes stale when the header changes. --- */
[data-scrollstack]{display:block}
[data-scrollstack] > *{
  position:sticky;
  top:var(--ss-top,120px);
  margin-bottom:var(--ss-gap,26px);
  transform-origin:50% 0;
  transform:translateY(var(--ss-y,0px)) scale(var(--ss-s,1));
  will-change:transform;
}
[data-scrollstack] > *:last-child{margin-bottom:0}
/* the stacked card underneath dims slightly so the top card stays readable */
[data-scrollstack] > *::before{
  content:"";position:absolute;inset:0;z-index:3;pointer-events:none;
  border-radius:inherit;background:#fff;opacity:var(--ss-fade,0);
  transition:opacity .18s linear;
}

/* --- staggered drawer nav: StaggeredMenu.
   Pure CSS — the links ride in one after another when app.js adds .active.
   nth-child covers 10 nav items, which is more than $navCategories ships. --- */
.drawer .drawer-nav a{
  opacity:0;
  transform:translateX(-16px);
  transition:opacity .34s ease,transform .34s cubic-bezier(.22,.61,.36,1);
}
.drawer.active .drawer-nav a{opacity:1;transform:none}
.drawer.active .drawer-nav a:nth-child(1){transition-delay:.07s}
.drawer.active .drawer-nav a:nth-child(2){transition-delay:.11s}
.drawer.active .drawer-nav a:nth-child(3){transition-delay:.15s}
.drawer.active .drawer-nav a:nth-child(4){transition-delay:.19s}
.drawer.active .drawer-nav a:nth-child(5){transition-delay:.23s}
.drawer.active .drawer-nav a:nth-child(6){transition-delay:.27s}
.drawer.active .drawer-nav a:nth-child(7){transition-delay:.31s}
.drawer.active .drawer-nav a:nth-child(8){transition-delay:.35s}
.drawer.active .drawer-nav a:nth-child(9){transition-delay:.39s}
.drawer.active .drawer-nav a:nth-child(n+10){transition-delay:.43s}
.drawer .drawer-foot{
  opacity:0;transform:translateY(10px);
  transition:opacity .34s ease .34s,transform .34s ease .34s;
}
.drawer.active .drawer-foot{opacity:1;transform:none}

/* --- tilt: TiltedCard — engine writes --tx/--ty/--ts on pointermove --- */
[data-tilt]{
  transform:perspective(900px) rotateX(var(--tx,0deg)) rotateY(var(--ty,0deg)) scale(var(--ts,1));
  transform-style:preserve-3d;
  transition:transform .38s cubic-bezier(.22,.61,.36,1);
}
[data-tilt].tilting{transition:transform .07s linear}

@media (prefers-reduced-motion:reduce){
  [data-scrollstack] > *{position:static;transform:none;will-change:auto}
  [data-scrollstack] > *::before{opacity:0}
  .drawer .drawer-nav a,.drawer.active .drawer-nav a,
  .drawer .drawer-foot,.drawer.active .drawer-foot{
    opacity:1;transform:none;transition:none;
  }
  [data-tilt],[data-tilt].tilting{transform:none;transition:none}
}

/* --- masonry: Masonry — CSS columns instead of a JS layout engine, so it
   reflows on resize for free. Opt-in: <div data-masonry data-masonry-cols="3">.
   Reading order becomes top-to-bottom per column, so only use it for galleries
   where order does not carry meaning. --- */
[data-masonry]{columns:var(--mc,3);column-gap:var(--mc-gap,18px)}
[data-masonry] > *{break-inside:avoid;margin:0 0 var(--mc-gap,18px)}
@media(max-width:900px){[data-masonry]{columns:2}}
@media(max-width:640px){[data-masonry]{columns:1}}

/* v-mobilenav — mobile bottom tab bar + "ALL MENU" bottom sheet, rendered by
   partials/mobile_nav.php on every public page. Hidden entirely above 768px:
   desktop/tablet keeps the header hamburger + off-canvas .drawer as-is.
   Lowest layer in the file, so shared selectors win without !important. */
.mnav,.msheet{display:none}

@media(max-width:768px){
  /* MENU now lives in the bottom bar — the header hamburger would be a second
     door to the same room, so it goes. .header-left [data-menu-open] is (0,2,0)
     and beats .icon-btn{display:grid} without !important. */
  .site-header .header-left [data-menu-open]{display:none}

  /* border-box is global, so min-height:100vh already absorbs this padding —
     no phantom 64px of scroll on short pages. */
  body{padding-bottom:calc(64px + env(safe-area-inset-bottom,0px))}
  .toast{bottom:calc(78px + env(safe-area-inset-bottom,0px))}

  /* --- bottom tab bar --- */
  .mnav{
    display:grid;grid-template-columns:repeat(5,1fr);align-items:center;
    position:fixed;left:0;right:0;bottom:0;z-index:70;
    padding-bottom:env(safe-area-inset-bottom,0px);
    background:var(--paper);border-top:1px solid var(--line);
    box-shadow:0 -6px 22px rgba(0,0,0,.05);
  }
  .mnav-item,.mnav-fab{
    display:grid;justify-items:center;align-content:center;gap:4px;
    height:62px;padding:0;border:0;background:transparent;
    color:var(--muted);font:inherit;cursor:pointer;
  }
  .mnav-ico{position:relative;display:block;font-size:19px;line-height:1}
  .mnav-label{font-size:9px;line-height:1;letter-spacing:.02em}
  .mnav-item.is-active{color:var(--ink)}
  .mnav-item.is-active .mnav-label{font-weight:500}
  .mnav-ico sup{
    position:absolute;top:-6px;right:-10px;min-width:15px;height:15px;padding:0 3px;
    border-radius:999px;background:var(--ink);color:#fff;
    display:grid;place-items:center;font-size:8px;line-height:1;
  }
  .mnav-fab{color:var(--ink)}
  .mnav-fab-dot{
    width:48px;height:48px;margin-top:-24px;border-radius:50%;
    background:var(--ink);color:#fff;border:3px solid var(--paper);
    display:grid;place-items:center;font-size:19px;
    box-shadow:0 10px 24px rgba(16,16,16,.26);
    transition:transform .2s cubic-bezier(.22,.61,.36,1);
  }
  .mnav-fab[aria-expanded="true"] .mnav-fab-dot{transform:rotate(90deg) scale(.94)}
  .mnav-fab .mnav-label{font-weight:500;letter-spacing:.1em}

  /* --- "ALL MENU" bottom sheet --- */
  .msheet{
    display:flex;flex-direction:column;
    position:fixed;left:0;right:0;bottom:0;z-index:92;
    max-height:86vh;background:var(--paper);
    border-radius:22px 22px 0 0;
    box-shadow:0 -20px 56px rgba(0,0,0,.2);
    padding-bottom:env(safe-area-inset-bottom,0px);
    transform:translateY(102%);
    transition:transform .3s cubic-bezier(.22,.61,.36,1);
  }
  .msheet.active{transform:none}
  /* touch-action:none so the drag-to-dismiss handler in app.js owns the gesture
     instead of the browser scrolling .msheet-body underneath it */
  .msheet-grip{display:grid;place-items:center;padding:10px 0 4px;touch-action:none}
  .msheet-grip span{display:block;width:42px;height:4px;border-radius:999px;background:#dcdcdc}
  .msheet-head{display:flex;align-items:center;gap:12px;padding:8px 18px 16px;touch-action:none}
  .msheet-badge{
    flex:0 0 auto;width:44px;height:44px;border-radius:14px;
    background:var(--ink);color:#fff;display:grid;place-items:center;font-size:18px;
  }
  .msheet-title{flex:1 1 auto;min-width:0;display:grid;gap:2px}
  .msheet-title strong{font-size:16px;font-weight:500;letter-spacing:-.025em}
  .msheet-title>span{font-size:9px;color:var(--muted);letter-spacing:.14em}
  .msheet-x{
    flex:0 0 auto;width:36px;height:36px;border:0;border-radius:50%;
    background:#f2f2f2;color:var(--ink);display:grid;place-items:center;
    font-size:13px;cursor:pointer;
  }
  .msheet-body{flex:1 1 auto;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;padding:0 16px 20px}
  .msheet-sec+.msheet-sec{margin-top:20px}
  .msheet-sec h4{
    position:relative;display:flex;align-items:center;gap:7px;
    margin:0 0 10px;padding-left:10px;
    font-size:13px;font-weight:500;letter-spacing:-.02em;
  }
  .msheet-sec h4:before{
    content:'';position:absolute;left:0;top:50%;transform:translateY(-50%);
    width:3px;height:14px;border-radius:2px;background:var(--ink);
  }
  .msheet-sec h4 span{font-size:9px;font-weight:400;color:var(--muted);letter-spacing:.14em}
  .msheet-sec h4 span:before{content:'\00b7\00a0'}

  /* --- tiles --- */
  .mtiles{display:grid;grid-template-columns:repeat(4,1fr);gap:9px}
  .mtile{
    display:grid;justify-items:center;align-content:start;gap:7px;text-align:center;
    /* min-height keeps a row level when one Thai label wraps to two lines —
       otherwise neighbouring tiles ended up visibly different heights. */
    min-height:104px;
    padding:14px 5px 12px;border:1px solid var(--line);border-radius:16px;
    background:var(--paper);
    transition:transform .16s ease,background .16s ease,border-color .16s ease;
  }
  .mtile:active{transform:scale(.955)}
  /* font-size/color are set explicitly here because `.mtile > span` (the EN
     label rule below) used to match this element too — the icon inherited
     7px muted grey and all but vanished. The label now carries .mtile-en. */
  .mtile-ico{
    width:40px;height:40px;border-radius:13px;background:#f2f2f2;
    display:grid;place-items:center;
    font-size:19px;line-height:1;letter-spacing:0;color:var(--ink);
  }
  .mtile strong{font-size:11px;font-weight:400;line-height:1.3}
  .mtile-en{font-size:8px;line-height:1;color:var(--muted);letter-spacing:.1em}
  .mtile.is-active{background:var(--ink);border-color:var(--ink);color:#fff}
  /* The icon colour has to be restated: without it the glyph inherited the
     tile's white text colour and disappeared into the white chip. */
  .mtile.is-active .mtile-ico{background:#fff;color:var(--ink)}
  .mtile.is-active .mtile-en{color:rgba(255,255,255,.62)}
}

@media(max-width:360px){
  .mtiles{gap:6px}
  .mtile{min-height:92px;padding:12px 2px 10px;border-radius:14px;gap:6px}
  .mtile-ico{width:34px;height:34px;font-size:16px;border-radius:11px}
  .mtile strong{font-size:10px}
}

@media (max-width:768px) and (prefers-reduced-motion:reduce){
  .msheet,.mtile,.mnav-fab-dot{transition:none}
  .mtile:active{transform:none}
}

/* v-newsbtn — newsletter CTA went white-on-white. StarBorder's ::after paints
   an inner fill so the conic-gradient only shows as a 1px ring; the default
   fill is --paper, which sat on top of .btn's black background (isolation
   creates a stacking context, so a z-index:-1 pseudo still covers the host's
   own background) and left white text on white. .btn is a DARK surface, so it
   takes the "light" variant — common.js now tags it that way. These rules pin
   the CTA's colours regardless of which variant it carries, so a stale cached
   common.js can't bring the invisible button back. */
.newsletter-form .btn[data-starborder]{color:#fff;background:var(--ink);border-color:var(--ink)}
.newsletter-form .btn[data-starborder]::after{background:var(--ink)}
.newsletter-form .btn[data-starborder]::before{
  background:conic-gradient(from 0deg,transparent 0 72%,rgba(255,255,255,.7) 84%,transparent 92%);
}
.newsletter-form .btn[data-starborder] i{color:inherit}

/* v-account — /account area redesign. The old shell was an admin console
   dropped into the public site: a pill tab row on --soft (an ADMIN token),
   600-weight labels, boxed white cards with 1px borders per block, and
   icon+chevron list rows. None of that vocabulary exists anywhere else here.
   Rebuilt on the site's own language — .kicker, weight-500 headings with
   negative letter-spacing and clamp(), hairline rules instead of card
   borders, and the same tile treatment as the mobile menu (v-mobilenav).
   Lowest layer, so it beats the v10 .account-* rules without !important. */

/* --- masthead ------------------------------------------------------- */
.acc-head{padding:44px 0 0}
.acc-head .container,.acc-tabs-wrap .container,.acc-body .container{width:min(calc(100% - 48px),1180px)}
.acc-id{display:flex;align-items:center;gap:18px;margin-top:15px;padding-bottom:26px}
.acc-av{
  flex:0 0 auto;width:66px;height:66px;border-radius:50%;overflow:hidden;
  display:grid;place-items:center;background:var(--ink);color:#fff;
  font-size:25px;font-weight:500;letter-spacing:-.03em;
}
.acc-av img{width:100%;height:100%;object-fit:cover}
.acc-id-copy{flex:1 1 auto;min-width:0}
.acc-id-copy h1{margin:0;font-size:clamp(30px,4.4vw,52px);font-weight:500;line-height:1;letter-spacing:-.05em}
.acc-meta{display:flex;flex-wrap:wrap;align-items:center;gap:5px 14px;margin:9px 0 0;font-size:11.5px;color:var(--muted)}
.acc-meta span{display:inline-flex;align-items:center;gap:5px}
.acc-out{
  flex:0 0 auto;display:inline-flex;align-items:center;gap:7px;
  height:38px;padding:0 15px;border:1px solid var(--line);border-radius:999px;
  font-size:11.5px;color:var(--muted);transition:border-color .16s,color .16s;
}
.acc-out:hover{border-color:var(--ink);color:var(--ink)}

/* --- section tabs: the header's underline nav, not a pill bar --------- */
.acc-tabs-wrap{border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.acc-tabs{display:flex;gap:28px;overflow-x:auto;scrollbar-width:none;scroll-snap-type:x proximity}
.acc-tabs::-webkit-scrollbar{display:none}
.acc-tab{
  position:relative;flex:0 0 auto;scroll-snap-align:center;
  display:inline-flex;align-items:center;gap:7px;padding:15px 0;
  font-size:12px;color:var(--muted);white-space:nowrap;transition:color .16s;
}
.acc-tab i{font-size:13px}
.acc-tab em{font-style:normal;font-size:8.5px;letter-spacing:.14em;opacity:.55}
.acc-tab:after{content:'';position:absolute;left:0;right:100%;bottom:-1px;height:2px;background:var(--ink);transition:.22s}
.acc-tab:hover{color:var(--ink)}
.acc-tab:hover:after,.acc-tab.is-active:after{right:0}
.acc-tab.is-active{color:var(--ink);font-weight:500}

/* --- body ------------------------------------------------------------ */
.acc-body{padding:34px 0 72px}
.acc-sec{margin-top:46px}
.acc-sec-head{
  display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap;
  margin-bottom:22px;padding-bottom:14px;border-bottom:1px solid var(--line);
}
.acc-sec-head h2{margin:7px 0 0;font-size:clamp(21px,2.4vw,30px);font-weight:500;line-height:1;letter-spacing:-.04em}
.acc-more{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;color:var(--muted);transition:color .16s}
.acc-more:hover{color:var(--ink)}

/* --- metric strip: hairline dividers, no cards ----------------------- */
.acc-metrics{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.acc-metrics .metric{padding:26px 18px;text-align:center;color:inherit;border-left:1px solid var(--line);transition:background .16s}
.acc-metrics .metric:first-child{border-left:0}
.acc-metrics a.metric:hover{background:#fafafa}
.acc-metrics .metric strong{display:block;font-size:clamp(28px,3.8vw,46px);font-weight:300;line-height:1;letter-spacing:-.05em}
.acc-metrics .metric span{display:block;margin-top:10px;font-size:12px}
.acc-metrics .metric em{display:block;margin-top:4px;font-style:normal;font-size:8.5px;letter-spacing:.14em;color:var(--muted)}

/* --- list rows ------------------------------------------------------- */
.acc-rows{display:grid}
.acc-row{
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto auto 16px;
  align-items:center;gap:16px;padding:17px 0;
  border-bottom:1px solid var(--line);color:inherit;
  transition:padding-left .18s,padding-right .18s;
}
.acc-row:hover{padding-left:9px;padding-right:9px}
.acc-row-no{font-size:13px;font-weight:500;letter-spacing:.02em}
.acc-row-meta{font-size:11.5px;color:var(--muted)}
.acc-row-amt{font-size:14px;font-weight:500;letter-spacing:-.02em;text-align:right}
.acc-row>i{justify-self:end;font-size:13px;color:var(--muted);transition:color .16s}
.acc-row:hover>i{color:var(--ink)}
.acc-pill{
  display:inline-flex;align-items:center;gap:5px;padding:4px 10px;
  border:1px solid var(--line);border-radius:999px;
  font-size:9.5px;letter-spacing:.06em;color:var(--muted);white-space:nowrap;
}
.acc-pill.ok{border-color:var(--ink);color:var(--ink)}

/* --- empty state: type, not a boxed icon ----------------------------- */
.acc-empty{padding:54px 0 58px;text-align:center}
.acc-empty strong{display:block;font-size:clamp(20px,2.6vw,28px);font-weight:500;letter-spacing:-.04em}
.acc-empty p{margin:9px 0 22px;font-size:12.5px;color:var(--muted)}

/* --- manage tiles: same vocabulary as the mobile menu ---------------- */
.acc-tiles{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-top:22px}
.acc-tile{
  position:relative;display:grid;align-content:start;gap:9px;
  padding:20px 18px 48px;border:1px solid var(--line);border-radius:var(--r);
  color:inherit;transition:background .18s,border-color .18s,color .18s;
}
.acc-tile>i:first-child{font-size:20px}
.acc-tile strong{font-size:13.5px;font-weight:500;letter-spacing:-.02em}
.acc-tile>span{font-size:9.5px;letter-spacing:.06em;color:var(--muted);transition:color .18s}
.acc-tile .arr{position:absolute;right:18px;bottom:18px;font-size:13px;color:var(--muted);transition:transform .18s,color .18s}
.acc-tile:hover{background:var(--ink);border-color:var(--ink);color:#fff}
.acc-tile:hover>span{color:rgba(255,255,255,.6)}
.acc-tile:hover .arr{color:#fff;transform:translateX(4px)}

/* --- flatten the v10 shell the secondary account pages still use ----- */
.account-wrap{width:min(calc(100% - 48px),1180px);max-width:none;margin:0 auto;padding:34px 0 72px}
.account-section{background:transparent;border:0;border-top:1px solid var(--line);border-radius:0;padding:24px 0;margin-bottom:0}
.account-section:first-child{border-top:0}
.account-section-head h2{font-size:clamp(19px,2.2vw,26px);font-weight:500;letter-spacing:-.04em}
.account-section-head{padding-bottom:14px;border-bottom:1px solid var(--line)}
.account-empty{padding:54px 0}
.account-empty i{display:none}
.account-empty .msg{font-size:clamp(19px,2.4vw,26px);letter-spacing:-.04em}
.account-quickaction{padding:16px 0}
.account-quickaction>i:first-child{font-size:16px}
.account-btn{min-height:42px;padding:0 20px}

@media(max-width:900px){
  .acc-tiles{grid-template-columns:repeat(2,1fr)}
  .acc-row{grid-template-columns:minmax(0,1fr) auto;gap:7px 14px}
  .acc-row-meta{grid-column:1;grid-row:2}
  .acc-pill{grid-column:2;grid-row:2;justify-self:end}
  .acc-row-amt{grid-column:2;grid-row:1}
  .acc-row>i{display:none}
}

@media(max-width:640px){
  .acc-head{padding:28px 0 0}
  .acc-head .container,.acc-tabs-wrap .container,.acc-body .container{width:min(calc(100% - 24px),1180px)}
  .acc-id{gap:14px;padding-bottom:20px}
  .acc-av{width:52px;height:52px;font-size:21px}
  .acc-out{width:38px;padding:0;justify-content:center;font-size:0;gap:0}
  .acc-out i{font-size:15px}
  .acc-tabs{gap:20px}
  .acc-tab em{display:none}
  .acc-body{padding:26px 0 56px}
  .acc-sec{margin-top:36px}
  .acc-metrics .metric{padding:18px 8px}
  .acc-metrics .metric span{margin-top:7px;font-size:10.5px}
  .acc-metrics .metric em{display:none}
  .account-wrap{width:min(calc(100% - 24px),1180px)}
  /* tiles become rule-separated rows — cards this narrow read as noise */
  .acc-tiles{grid-template-columns:1fr;gap:0;margin-top:14px}
  .acc-tile{
    grid-template-columns:24px minmax(0,1fr);align-items:center;gap:3px 14px;
    padding:15px 0;border:0;border-bottom:1px solid var(--line);border-radius:0;
  }
  .acc-tile>i:first-child{grid-row:1/3;font-size:17px;color:var(--muted)}
  .acc-tile strong,.acc-tile>span{grid-column:2}
  .acc-tile .arr{right:0;bottom:auto;top:50%;transform:translateY(-50%)}
  .acc-tile:hover{background:transparent;border-color:var(--line);color:inherit}
  .acc-tile:hover>span{color:var(--muted)}
  .acc-tile:hover .arr{color:var(--muted);transform:translateY(-50%)}
}

@media (prefers-reduced-motion:reduce){
  .acc-tab:after,.acc-row,.acc-tile,.acc-tile .arr,.acc-out,.acc-more,.acc-metrics .metric{transition:none}
  .acc-row:hover{padding-left:0;padding-right:0}
  .acc-tile:hover .arr{transform:none}
}

/* v-account-b — 4-up metric strip (/account/orders) + spacing for the blocks
   that follow a .acc-sec-head. Kept in its own comment block rather than
   edited into v-account above, per the layer rules. */
.acc-metrics-4{grid-template-columns:repeat(4,1fr)}
.acc-sec-head+.acc-metrics,
.acc-sec-head+.card-grid,
.acc-sec-head+.ord-hist-list,
.acc-metrics+.ord-hist-list,
.acc-metrics+.account-empty{margin-top:0}
.acc-metrics{margin-bottom:24px}
.acc-body .card-grid{margin-top:0}

@media(max-width:900px){
  .acc-metrics-4{grid-template-columns:repeat(2,1fr)}
  .acc-metrics-4 .metric:nth-child(odd){border-left:0}
  .acc-metrics-4 .metric:nth-child(n+3){border-top:1px solid var(--line)}
}

/* v-herofix — the hero READ button rendered as a full-width white bar across
   the whole slide. Cause: .hero-copy is a flex column and never set
   align-items, so every child inherited `stretch`. h1/p hid it behind their
   own max-width; the button and the kicker had none, so they spanned the
   container. Also clamps the headline: a 3-line Thai title at 68px overflowed
   the fixed-height slide and .hero-slider{overflow:hidden} cut it in half. */
.hero-copy{align-items:flex-start;padding-top:120px}
.hero-copy>*{max-width:100%}
.hero-copy .btn{align-self:flex-start;width:auto;min-width:0;padding:0 24px;gap:9px}
.hero-copy .btn i{font-size:14px}
.hero-copy h1{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;
  overflow:hidden;margin-bottom:16px;
}
.hero-copy p{
  display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;
  overflow:hidden;
}

/* Slider controls: circles that match the site's pill language instead of
   2px-radius boxes, and a dot row that reads as one control. */
.hero-control{
  width:40px;height:40px;border-radius:50%;
  border:1px solid rgba(255,255,255,.32);background:rgba(0,0,0,.22);
  font-size:15px;transition:background .16s,border-color .16s,color .16s;
}
.hero-control:hover{background:#fff;border-color:#fff;color:var(--ink)}
.hero-nav{gap:8px}
.hero-dots{gap:9px}
.hero-dots button{
  width:7px;height:7px;background:rgba(255,255,255,.4);
  transition:width .2s ease,background .2s ease;
}
.hero-dots button.active{width:26px;height:7px;border-radius:999px;background:#fff}

@media(max-width:1024px){.hero-copy{padding-top:100px}}
@media(max-width:768px){
  .hero-copy{padding-top:84px}
  .hero-copy h1{-webkit-line-clamp:4}
  .hero-control{width:36px;height:36px;font-size:13px}
}
@media(max-width:640px){
  .hero-copy{padding-top:74px}
  .hero-copy p{-webkit-line-clamp:2}
}

@media (prefers-reduced-motion:reduce){
  .hero-control,.hero-dots button{transition:none}
}

/* v-pblock — product block inside an article body (partials/blocks/product.php).
   The block used to render a grey placeholder card with inline styles; now it
   is a real product link, styled in the article's own editorial language
   rather than the admin's --soft box it inherited before. */
.pblock{
  display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:16px;
  margin:34px 0;padding:16px;border:1px solid var(--line);border-radius:var(--r);
  color:inherit;transition:border-color .18s,background .18s;
}
.pblock:hover{border-color:var(--ink);background:#fafafa}
.pblock-media{width:84px;height:84px;border-radius:10px;overflow:hidden;flex:0 0 auto}
.pblock-media img{width:100%;height:100%;object-fit:cover}
.pblock-body{display:grid;gap:5px;min-width:0}
.pblock-kicker{font-size:9px;font-weight:600;letter-spacing:.14em;color:var(--muted)}
.pblock-name{font-size:16px;font-weight:500;letter-spacing:-.025em;line-height:1.25}
.pblock-price{font-size:13px;display:flex;align-items:baseline;gap:9px;flex-wrap:wrap}
.pblock-price s{color:var(--muted);font-size:11.5px}
.pblock-price em{font-style:normal;font-size:9.5px;letter-spacing:.1em;color:var(--muted);border:1px solid var(--line);border-radius:999px;padding:2px 8px}
.pblock-arrow{font-size:15px;color:var(--muted);transition:transform .18s,color .18s}
.pblock:hover .pblock-arrow{color:var(--ink);transform:translateX(4px)}

@media(max-width:640px){
  .pblock{grid-template-columns:auto 1fr;gap:13px;padding:13px}
  .pblock-media{width:64px;height:64px}
  .pblock-name{font-size:14px}
  .pblock-arrow{display:none}
}

@media (prefers-reduced-motion:reduce){
  .pblock,.pblock-arrow{transition:none}
  .pblock:hover .pblock-arrow{transform:none}
}

/* v-news — /news, /news-world and /news/category/{slug}.
   The page used to be the old sub-brand layout, styled inline for a DARK
   theme — rgba(0,0,0,.5) chips behind var(--mu) text. v-tokenfix remapped the
   old token names to monochrome but cannot rewrite hardcoded rgba(), so those
   chips rendered as dark grey blocks on today's light page. Rebuilt as a real
   editorial front page — masthead, lead story, numbered latest rows, rail —
   entirely on this project's tokens and type scale. */

/* --- masthead ------------------------------------------------------- */
.nhead{padding:46px 0 0}
.nhead-top{display:flex;align-items:center;justify-content:space-between;gap:20px;flex-wrap:wrap}
.nhead-date{font-size:10px;letter-spacing:.14em;color:var(--muted);text-transform:uppercase}
.nhead h1{
  margin:16px 0 0;font-size:clamp(44px,7vw,86px);font-weight:500;
  line-height:.94;letter-spacing:-.055em;
}
.nhead-deck{max-width:620px;margin:14px 0 0;font-size:14px;font-weight:300;color:var(--muted);line-height:1.7}

/* Filter row — scrolls sideways instead of wrapping into a wall of pills. */
.nfilter{
  display:flex;gap:8px;margin:24px 0 0;padding:0 0 24px;
  overflow-x:auto;scrollbar-width:none;scroll-snap-type:x proximity;
}
.nfilter::-webkit-scrollbar{display:none}
.nfilter-item{
  flex:0 0 auto;scroll-snap-align:start;
  display:inline-flex;align-items:center;height:34px;padding:0 15px;
  border:1px solid var(--line);border-radius:999px;
  font-size:11.5px;color:var(--muted);white-space:nowrap;
  transition:border-color .16s,color .16s,background .16s;
}
.nfilter-item:hover{border-color:var(--ink);color:var(--ink)}
.nfilter-item.is-active{background:var(--ink);border-color:var(--ink);color:#fff}

/* --- news card grid --------------------------------------------------
   Was a lead story + 3 runners + a numbered list of rows below. Reference
   layout for this rebuild uses one uniform grid of cards instead — no
   separate hero treatment — so this replaces the .nlead / .nrunner / .nrow
   families wholesale rather than adding yet another layer on top of them.
   (⚠️ the selector names are written without their trailing wildcard on
   purpose: an asterisk followed by a slash closes a comment early — that
   typo used to end this comment right here and hand the next rule to the
   parser as garbage, which is why .nbody silently lost its padding.) */
.nbody{padding:52px 0 74px}
.news-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:28px 20px}
.news-card{display:block;color:inherit}
.news-card-media{
  position:relative;display:block;overflow:hidden;
  border-radius:var(--r);background:#eee;aspect-ratio:4/5;
}
.news-card-media img{width:100%;height:100%;object-fit:cover;transition:transform .4s cubic-bezier(.22,.61,.36,1)}
.news-card:hover .news-card-media img{transform:scale(1.03)}
.news-card-badge{
  position:absolute;left:10px;top:10px;z-index:1;
  padding:5px 11px;border-radius:999px;color:#fff;
  font-size:9.5px;font-weight:500;letter-spacing:.1em;
}
.news-card-body{padding:14px 1px 0}
.news-card-body h3{
  margin:0 0 7px;font-size:15.5px;font-weight:500;line-height:1.35;letter-spacing:-.02em;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.news-card-body p{
  margin:0 0 9px;font-size:12px;font-weight:300;color:var(--muted);line-height:1.6;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.news-card-body small{display:block;font-size:10.5px;color:var(--muted)}

/* Small "external link" marker on a card's media. */
.story-ext{
  position:absolute;top:9px;right:9px;z-index:2;
  width:25px;height:25px;border-radius:50%;
  background:rgba(255,255,255,.92);color:var(--ink);
  display:grid;place-items:center;font-size:10.5px;
}

.news-count{
  flex:0 0 auto;align-self:center;
  font-size:10px;letter-spacing:.1em;color:var(--muted);
  border:1px solid var(--line);border-radius:999px;padding:5px 11px;white-space:nowrap;
}

/* --- rail ----------------------------------------------------------- */
.news-layout{display:grid;grid-template-columns:minmax(0,1fr) 290px;gap:48px;align-items:start}
.news-sidebar{display:flex;flex-direction:column;gap:30px;position:sticky;top:96px}

.nside{border-top:1px solid var(--line);padding-top:16px}
.nside .kicker{margin-bottom:13px}

.nmost{list-style:none;margin:0;padding:0;display:grid}
.nmost li{display:grid;grid-template-columns:26px minmax(0,1fr);gap:11px;align-items:baseline;padding:11px 0;border-bottom:1px solid var(--line)}
.nmost li span{font-size:17px;font-weight:300;color:#c8c8c8;letter-spacing:-.03em;line-height:1}
.nmost li a{font-size:12.5px;line-height:1.5;color:var(--ink)}
.nmost li a:hover{text-decoration:underline;text-underline-offset:3px}

.nside-list{display:grid}
.nside-list a{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:11px 0;border-bottom:1px solid var(--line);
  font-size:12.5px;color:var(--ink);transition:padding-left .16s;
}
.nside-list a:hover{padding-left:7px}
.nside-list a b{font-size:10.5px;font-weight:400;color:var(--muted)}
.nside-list a.is-active{font-weight:500}
.nside-list a.is-active b{color:var(--ink)}

.pagination .pg-gap{display:grid;place-items:center;width:22px;height:38px;color:var(--muted);font-size:13px}

@media(max-width:1024px){
  .news-layout{grid-template-columns:1fr;gap:44px}
  .news-sidebar{position:static;flex-direction:row;flex-wrap:wrap;gap:26px}
  .news-sidebar > *{flex:1 1 250px}
  .news-grid{grid-template-columns:repeat(3,1fr)}
}
@media(max-width:768px){
  .news-grid{grid-template-columns:repeat(2,1fr);gap:22px 14px}
}
@media(max-width:640px){
  .nhead{padding:30px 0 0}
  .nfilter{margin-top:18px;padding-bottom:18px}
  .nfilter-item{height:31px;padding:0 13px;font-size:11px}
  .nbody{padding:36px 0 56px}
  .news-card-body h3{font-size:14px}
  .news-sidebar{flex-direction:column}
}
@media(max-width:420px){
  .news-grid{grid-template-columns:1fr;gap:18px}
}

@media (prefers-reduced-motion:reduce){
  .nfilter-item,.nside-list a,.news-card-media img{transition:none}
  .news-card:hover .news-card-media img{transform:none}
  .nside-list a:hover{padding-left:0}
}

/* v-bannerslot — banner_slot() in Helpers/functions.php has always emitted
   .banner-slot / .banner-slot-empty markup, but no stylesheet ever defined
   those classes. The "YOUR AD HERE" placeholder therefore rendered as bare
   unstyled text on every page that calls the helper (visible on /news).
   Styled here in the site's own language so it reads as a deliberate empty
   ad slot rather than broken markup. */
.banner-slot{display:block;color:inherit}
.banner-slot img{border-radius:var(--r)}
.banner-slot-label{
  margin-top:6px;font-size:8.5px;letter-spacing:.14em;color:var(--muted);text-transform:uppercase;
}
.banner-slot-empty-in{
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;
  padding:22px 18px;text-align:center;
  border:1px dashed var(--line);border-radius:var(--r);
  color:var(--muted);transition:border-color .18s,color .18s;
}
.banner-slot-empty:hover .banner-slot-empty-in{border-color:var(--ink);color:var(--ink)}
.banner-slot-empty-in i{font-size:20px;opacity:.5}
.banner-slot-title{font-size:11px;font-weight:500;letter-spacing:.14em;color:var(--ink)}
.banner-slot-sub{font-size:10px;line-height:1.5}
.banner-slot-cta{
  margin-top:4px;font-size:10.5px;color:var(--ink);
  border-bottom:1px solid var(--line);padding-bottom:2px;
}

@media (prefers-reduced-motion:reduce){
  .banner-slot-empty-in{transition:none}
}

/* v-newsarticle — /news/{slug} and /news-world/{slug}.
   The view (public/news/show.php) has always rendered .na-* markup, but NOT
   ONE of those ~40 classes was ever defined in any stylesheet — the article
   page shipped completely unstyled: a bare column of text with full-bleed
   images. The markup itself is sound (breadcrumb → header grid → blocks →
   share → rail) and drives real logic (YouTube playlists, galleries, banner
   blocks), so it is left alone and dressed here instead of rewritten.
   Typography follows the existing article page: weight 500 headings, negative
   letter-spacing, body line-height 1.86. */

.news-article-wrap{width:min(calc(100% - 48px),var(--max));margin:0 auto;padding:36px 0 76px}
.news-article-grid{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:52px;align-items:start}
.news-article-main{min-width:0}

/* --- header ---------------------------------------------------------- */
.na-header-grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:38px;align-items:center;margin-bottom:36px}
.na-header-text{min-width:0}

.na-breadcrumb{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:10px;letter-spacing:.12em;color:var(--muted);margin-bottom:16px}
.na-breadcrumb a{color:var(--muted)}
.na-breadcrumb a:hover{color:var(--ink)}
.na-breadcrumb i{font-size:9px;opacity:.5}

/* The badge carries an inline background from the category's colour. Keep the
   shape neutral so a bright category colour still reads on the light page. */
.na-category-badge{
  display:inline-flex;align-items:center;height:22px;padding:0 10px;
  border-radius:999px;color:#fff;
  font-size:9px;font-weight:600;letter-spacing:.12em;
}
.na-title{
  margin:14px 0 0;font-size:clamp(30px,4.4vw,58px);font-weight:500;
  line-height:1.02;letter-spacing:-.05em;
}
.na-excerpt{margin:16px 0 0;max-width:620px;font-size:15px;font-weight:300;color:var(--muted);line-height:1.75}
.na-meta{display:flex;align-items:center;gap:18px;flex-wrap:wrap;margin-top:20px;padding-top:16px;border-top:1px solid var(--line);font-size:11px;color:var(--muted)}
.na-meta span{display:inline-flex;align-items:center;gap:6px}

.na-header-cover{border-radius:var(--r);overflow:hidden;background:#eee;aspect-ratio:4/5}
.na-header-cover img{width:100%;height:100%;object-fit:cover}

/* --- body ------------------------------------------------------------ */
.na-content{max-width:720px;font-size:16px;line-height:1.86;color:var(--ink)}
.na-content p{margin:0 0 22px}
.na-content a{text-decoration:underline;text-underline-offset:3px}
.na-content img{border-radius:var(--r);margin:26px 0}
.na-content h2,.na-content h3{font-weight:500;letter-spacing:-.03em;line-height:1.2}
.na-content h2{font-size:clamp(21px,2.4vw,30px);margin:36px 0 14px}
.na-content h3{font-size:19px;margin:30px 0 12px}
.na-content blockquote{
  margin:30px 0;padding:4px 0 4px 22px;border-left:2px solid var(--ink);
  font-size:19px;font-weight:300;line-height:1.6;letter-spacing:-.02em;
}
.na-content ul,.na-content ol{margin:0 0 22px;padding-left:22px}
.na-content li{margin-bottom:8px}
.na-content figure{margin:28px 0}
.na-content figcaption{margin-top:9px;font-size:11.5px;color:var(--muted)}

.na-youtube-wrap{margin:28px 0}

/* --- gallery --------------------------------------------------------- */
.na-gallery{margin:36px 0}
.na-gallery-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:10px}
.na-gallery-item{
  position:relative;aspect-ratio:4/5;border-radius:12px;overflow:hidden;
  background-size:cover;background-position:center;background-color:#eee;
  cursor:zoom-in;
}
.na-gallery-caption{
  position:absolute;left:0;right:0;bottom:0;padding:22px 12px 10px;
  background:linear-gradient(transparent,rgba(0,0,0,.72));
  color:#fff;font-size:10.5px;line-height:1.5;
}

/* --- tags ------------------------------------------------------------ */
.na-tags{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:36px 0 0;padding-top:22px;border-top:1px solid var(--line)}
.na-tags-label{font-size:9px;font-weight:600;letter-spacing:.14em;color:var(--muted)}
.na-tag{
  display:inline-flex;align-items:center;height:28px;padding:0 12px;
  border:1px solid var(--line);border-radius:999px;
  font-size:11px;color:var(--muted);
}

/* --- share ----------------------------------------------------------- */
.na-share{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:30px;padding-top:22px;border-top:1px solid var(--line)}
.na-share-label{font-size:9px;font-weight:600;letter-spacing:.14em;color:var(--muted)}
.na-share-buttons{display:flex;gap:8px;flex-wrap:wrap}
.na-share-btn{
  display:inline-flex;align-items:center;gap:7px;height:36px;padding:0 15px;
  border:1px solid var(--line);border-radius:999px;
  font-size:11.5px;color:var(--muted);
  transition:border-color .16s,color .16s;
}
/* Monochrome on purpose — brand colours per network would be the only
   saturated thing on the page. */
.na-share-btn:hover{border-color:var(--ink);color:var(--ink)}

/* --- rail ------------------------------------------------------------ */
.news-article-sidebar{min-width:0}
.na-sidebar-sticky{position:sticky;top:96px;display:flex;flex-direction:column;gap:30px}
.na-section-title{font-size:9px;font-weight:600;letter-spacing:.14em;color:var(--muted);margin-bottom:13px;text-transform:uppercase}
.na-related{border-top:1px solid var(--line);padding-top:16px}
.na-related-list{display:grid}
.na-related-item{
  display:grid;grid-template-columns:72px minmax(0,1fr);gap:12px;align-items:center;
  padding:12px 0;border-bottom:1px solid var(--line);color:inherit;
  transition:padding-left .16s;
}
.na-related-item:hover{padding-left:6px}
.na-related-thumb{aspect-ratio:4/5;border-radius:9px;background-size:cover;background-position:center;background-color:#eee}
.na-related-title{font-size:12.5px;font-weight:400;line-height:1.45;letter-spacing:-.01em}
.na-related-meta{margin-top:5px;font-size:10px;color:var(--muted)}

/* --- YouTube playlist queue panel (styles for it are emitted inline by the
   view; these only fix the pieces that referenced the old dark theme) --- */
.na-pl{border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.na-pl-head .t{font-weight:500;letter-spacing:-.01em}

@media(max-width:1024px){
  .news-article-grid{grid-template-columns:1fr;gap:44px}
  .na-sidebar-sticky{position:static;flex-direction:row;flex-wrap:wrap;gap:26px}
  .na-sidebar-sticky > *{flex:1 1 250px}
  .na-header-grid{grid-template-columns:1fr;gap:24px}
  .na-header-cover{aspect-ratio:16/9}
}
@media(max-width:640px){
  .news-article-wrap{width:min(calc(100% - 24px),var(--max));padding:24px 0 56px}
  .na-content{font-size:15px}
  .na-content blockquote{font-size:17px;padding-left:16px}
  .na-meta{gap:12px;font-size:10.5px}
  .na-share{flex-direction:column;align-items:flex-start;gap:10px}
  .na-sidebar-sticky{flex-direction:column}
}

@media (prefers-reduced-motion:reduce){
  .na-share-btn,.na-related-item{transition:none}
  .na-related-item:hover{padding-left:0}
}

/* v-newsarticle-b — the four .na-* classes the first pass missed.
   .na-share-{fb,tw,line} were per-network brand-colour hooks in the old
   theme; here they stay monochrome and only carry the icon colour, so the
   share row reads as one control instead of three coloured buttons. */
.na-related-info{min-width:0}
.na-share-fb i,.na-share-tw i,.na-share-line i{font-size:13px}
.na-share-fb:hover,.na-share-tw:hover,.na-share-line:hover{background:var(--ink);border-color:var(--ink);color:#fff}

/* v-a11y — keyboard + screen-reader baseline. Three gaps this closes:

   1. FOCUS. The whole stylesheet had exactly one :focus-visible rule (the
      StarBorder button in v-motion) while 4 rules here and 14 inline styles in
      the section views set outline:none/0 with nothing put back. Tabbing the
      site gave no indication of where you were — WCAG 2.4.7 (AA) and 2.4.13
      Focus Appearance (WCAG 2.2 AA) both fail on that. The ring below is drawn
      with outline + outline-offset rather than box-shadow so it survives on
      elements that already own their box-shadow (.story, .metric, StarBorder),
      and :focus-visible means mouse users never see it.
      Declared last so it beats the earlier outline:0 rules on equal
      specificity — no !important, same trick the v-motion layer uses.
   2. SKIP LINK. Neither layout had one, so a keyboard user re-tabbed the whole
      header + subnav + mega menu on every page (WCAG 2.4.1). layouts/public.php
      and layouts/admin.php now render one as the first focusable element; it is
      off-screen until focused.
   3. .sr-only. Referenced by the OTP inputs, the newsletter field and the admin
      topbar search to give controls an accessible name without changing the
      visual design. It never existed in either stylesheet.                  */

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

/* Specificity, not !important. The section views declare their own
   `outline:none` inside <style> blocks that the browser sees *after* this
   file, and the strongest of them is `.ov-field input:focus` = (0,2,1). This
   selector is (0,3,2) — two pseudo-classes in :not() plus :focus-visible over
   html+body — so it wins everywhere without adding to the !important list
   CLAUDE.md keeps at four entries. The :not(:disabled) also stops a disabled
   control from drawing a ring it can never act on, and :not([tabindex="-1"])
   keeps the skip-link target from outlining the whole <main>. */
html body :focus-visible:not(:disabled):not([tabindex="-1"]){
  outline:2px solid var(--ink);
  outline-offset:2px;
  border-radius:3px;
}
/* On the ink-coloured surfaces (.btn, .utility, .badge, drawer footer) a black
   ring on black is invisible — flip it to paper there. */
html body .btn:focus-visible,html body .badge:focus-visible,
html body .utility a:focus-visible,html body .social a:focus-visible,
html body .toast a:focus-visible{
  outline-color:#fff;
  outline-offset:2px;
}
/* .btn.light / .btn.ghost sit on paper again, so flip back. */
html body .btn.light:focus-visible,html body .btn.ghost:focus-visible{outline-color:var(--ink)}

.skip-link{
  position:absolute;left:8px;top:-60px;z-index:200;
  display:inline-flex;align-items:center;gap:8px;
  padding:11px 16px;border-radius:999px;
  background:var(--ink);color:#fff;
  font-size:12px;font-weight:500;letter-spacing:-.01em;
  transition:top .18s;
}
.skip-link:focus{top:8px;outline:2px solid #fff;outline-offset:-4px}

@media (prefers-reduced-motion:reduce){
  .skip-link{transition:none}
}

/* v-megareal — mega menu on real data only (no placeholder cards).
   Cards now come from published posts; a post without a cover image gets
   .mega-card-ph so the track keeps its rhythm instead of a broken <img>. */
.mega-card-ph{display:block;width:100%;aspect-ratio:4/5;border-radius:8px;background:#eee}

/* v-news-c — the /news rewrite. The v-news layer above styled a markup that
   the view never shipped (it was still the old inline-styled sub-brand
   page); app/Views/public/news/index.php now renders .nhead/.news-grid, and
   these are the pieces that layer never covered: the masthead search, the
   section head above the grid, and the empty state. */

/* Masthead search — one underline, no box, so it reads as part of the
   masthead rather than a form dropped on top of it. */
.nsearch{
  display:flex;align-items:center;gap:10px;
  max-width:420px;margin:20px 0 0;padding:0 0 9px;
  border-bottom:1px solid var(--line);
  transition:border-color .18s;
}
.nsearch:focus-within{border-color:var(--ink)}
.nsearch i{font-size:13px;color:var(--muted)}
.nsearch input{
  flex:1;min-width:0;border:0;outline:0;background:transparent;
  font-size:13px;font-weight:300;color:var(--ink);
}
.nsearch input::placeholder{color:var(--muted)}
.nsearch-clear{display:grid;place-items:center;width:22px;height:22px;border-radius:50%;font-size:10px;color:var(--muted)}
.nsearch-clear:hover{background:#f2f2f2;color:var(--ink)}

/* Section head above the numbered rows. */
.nbody-head{display:flex;align-items:center;justify-content:space-between;gap:16px;margin:0 0 4px}

/* Empty state — a category or search with nothing in it is a normal state on
   a young desk, so it gets the same quiet treatment as the rest of the page. */
.nempty{
  display:grid;justify-items:center;gap:9px;text-align:center;
  padding:74px 24px;border-top:1px solid var(--line);
}
.nempty i{font-size:28px;color:#cfcfcf}
.nempty p{margin:4px 0 0;font-size:16px;font-weight:500;letter-spacing:-.02em}
.nempty small{font-size:12px;font-weight:300;color:var(--muted)}
.nempty .btn{margin-top:12px}

@media(max-width:640px){
  .nsearch{max-width:none;margin-top:16px}
  .nbody-head{flex-wrap:wrap;gap:10px}
  .nempty{padding:52px 12px}
}

@media (prefers-reduced-motion:reduce){
  .nsearch{transition:none}
}

/* v-brandlogo — the logo uploaded at /admin/settings/general now renders in
   the header, footer and drawer through partials/brand.php. It ships as a
   black PNG on transparency, so the copy sitting on a dark surface (footer,
   and anywhere else brand.php is included with $brandOnDark) is flipped to
   solid white rather than vanishing into the background. */
.brand-logo{
  height:26px;width:auto;max-width:190px;
  object-fit:contain;display:block;
}
.brand-logo.is-light{filter:brightness(0) invert(1)}

/* .brand is a flex row in the drawer/footer and plain type in the header —
   both need the image to stop inheriting the wordmark's letter-spacing box. */
.brand:has(.brand-logo){letter-spacing:normal;line-height:0}

@media(max-width:900px){.brand-logo{height:22px;max-width:150px}}
@media(max-width:640px){.brand-logo{height:20px;max-width:130px}}

/* v-megafix — mega dropdown ตอนมีการ์ดน้อย
   เดิม .mega-track ใช้ grid-auto-columns:minmax(220px,1fr) — ถ้าแท็บนั้นมีบทความ
   ใบเดียว 1fr จะกินความกว้าง container ทั้งแถบ (~1390px) แล้ว aspect-ratio:.78
   ก็ดันความสูงไปราว 1700px กลายเป็นกล่องเทาว่างเต็มจอ ดูเหมือนหน้าเว็บพัง
   แถวที่มี 5 ใบขึ้นไปยังใช้ 1fr เหมือนเดิม (เต็มแถบพอดี) ส่วนแถวที่ไม่ถึง 5 ใบ
   ตรึงความกว้างเท่ากับ 1 ใน 5 คอลัมน์ แล้วชิดซ้าย ไม่ให้ยืดกินทั้งแถว */
.mega-track:not(:has(> :nth-child(5))){grid-auto-columns:minmax(220px,calc((100% - 56px) / 5));justify-content:start}

/* บทความที่ยังไม่มีรูปปก: กล่อง #eee เปล่า ๆ อ่านเป็น "รูปโหลดไม่ขึ้น"
   ใส่ wordmark จาง ๆ ให้เห็นว่าตั้งใจเว้นไว้ */
.mega-card-ph{display:grid;place-items:center;background:linear-gradient(135deg,#f4f4f4,#e4e4e4)}
.mega-card-ph::after{content:"STRTWR";font-size:11px;font-weight:500;letter-spacing:.3em;color:#b8b8b8}

/* ลูกศรเลื่อนที่เลื่อนอะไรไม่ได้ (การ์ดไม่ล้นแถว) — ซ่อนทิ้ง
   คลาสนี้ใส่โดย IIFE v-megafix ใน common.js ตอนพาเนลถูกเปิด */
.mega-controls.is-static{display:none}

/* v-nooverflow — ฝั่ง public: กัน grid item ดัน track จนหน้าเลื่อนข้าง
   ใช้ min-width:0 ที่ "ลูกของ grid" แทนการประกาศ grid-template-columns ใหม่
   เพราะ selector พวกนี้ถูกประกาศซ้ำใน media query หลายชั้น (feed-item มี 4 รอบ)
   ถ้าประกาศ track ใหม่ที่ layer นี้จะไปทับค่าของ breakpoint ทั้งหมด */
.mainbar>*,.now-item>*,.feed-item>*,.most-row>*,.cat-title>*,.article-head-grid>*,
.account-layout>*,.cart-layout>*,.cart-item>*,.search-result>*,.article-layout>*,
.rank-item>*,.news-layout>*,.product-detail>*,.split>*{min-width:0}

/* ตาข่ายกันพลาด: URL ยาว ๆ / token / คำเดี่ยวที่ยาวเกินคอลัมน์ ให้ตัดบรรทัด
   แทนที่จะทะลุกรอบ (break-word ไม่กระทบการตัดคำปกติ) */
body{overflow-wrap:break-word}
iframe,video,canvas,table{max-width:100%}

/* v-theme — คอมโพเนนต์ที่ admin กับ public ต้องหน้าตาเหมือนกัน
   `.status` / `.pill` เดิมมีแค่ใน admin.css แต่ helper กลาง (badges.php) ถูก
   เรียกจากหน้า public ด้วย (confirm · my_tickets · ticket) ซึ่งโหลดแค่ไฟล์นี้
   badge เลยไม่มีสไตล์เลย — ก๊อปนิยามเดียวกันมาไว้ที่นี่ */
.status{display:inline-flex;align-items:center;gap:5px;min-height:23px;padding:0 8px;border-radius:999px;background:#f0f0f0;color:#666;font-size:8.5px;white-space:nowrap}
.status:before{content:'';width:5px;height:5px;border-radius:50%;background:#888}
.status.live{background:#edf6f0;color:var(--success)}.status.live:before{background:var(--success)}
.status.review{background:#fff6e8;color:var(--warning)}.status.review:before{background:var(--warning)}
.status.draft{background:#f1f1f1;color:#777}
.status.scheduled{background:#eef1f7;color:#486186}.status.scheduled:before{background:#486186}
.status.low{background:#fff1f0;color:var(--danger)}.status.low:before{background:var(--danger)}
.pill{display:inline-flex;align-items:center;min-height:24px;padding:0 8px;border:1px solid #e0e0e0;border-radius:999px;font-size:8.5px;color:#555;background:#fff;white-space:nowrap}

/* v-megaimg */
/* mega-card ตอนนี้เรนเดอร์ .mega-card-ph ไว้เสมอ ไม่ใช่ else ของ <img> อีกแล้ว
   ปกติซ่อนไว้ใต้เงื่อนไข "มี img เป็นพี่ก่อนหน้า" — พอ onerror สั่ง this.remove()
   ตัว img หายไป selector นี้เลยไม่ match แล้ว ph โผล่มาแทนที่เอง (ไม่ต้องพึ่ง JS ต่อ)
   specificity 0,2,1 ชนะ .mega-card-ph (0,1,0) ทั้งบรรทัด base และ layer ที่ใส่ ::after */
.mega-card img + .mega-card-ph{display:none}

/* v-autheditorial — /login /register /login/verify /register/verify /forgot
   /forgot/reset /register/line /account/line ยังเป็น "กล่องฟอร์มกลางจอ" ของ
   layer v10: การ์ดขาวขอบ 1px radius 18px + หัวข้อกลางจอ + ช่องกรอกแบบกล่อง
   — เป็นคำศัพท์ของแอป/แดชบอร์ด ซึ่งไม่มีที่ไหนในเว็บนี้ใช้ (เหตุผลเดียวกับที่ layer v-account ยุบกล่องของ /account ทิ้ง)

   เปลี่ยนเป็นภาษาเดียวกับที่เหลือ: .kicker เหนือหัวข้อ · หัวข้อ clamp() weight
   500 letter-spacing ติดลบ · เส้น hairline แทนขอบการ์ด · ช่องกรอกเป็นเส้นใต้
   ปุ่มยังเป็น pill เพราะ pill เป็นของเดิมในธีมอยู่แล้ว (.btn ทั้งเว็บ 999px)

   อยู่ล่างสุดของไฟล์ จึงชนะ v10 + v-authpolish ด้วยลำดับ ไม่ต้องใช้ !important
   ไอคอนยังอยู่ครบทุกจุด แต่ปรับน้ำหนักให้เข้าธีม: ไอคอนหัวข้อไม่ใช่แบดจ์ดำ
   อีกแล้ว แต่ย้ายไปยืนในบรรทัด kicker ต่อจากขีด (▬▬ ⇥ WELCOME BACK) ส่วน
   ไอคอนใน label / ในช่องกรอก / ใน stepper ใช้สีจาง ขนาดพอ ๆ ตัวอักษร */
.auth-wrap{width:min(calc(100% - 48px),540px);margin:0 auto;padding:52px 0 78px}
.auth-card{background:transparent;border:0;border-radius:0;padding:0;max-width:none}

/* masthead — ในไฟล์ view ลำดับคือ h1 มาก่อน subtitle ใช้ order สลับที่แทน
   การไปแก้ markup ทั้ง 8 ไฟล์ · row wrap เพื่อให้ไอคอนกับ kicker อยู่บรรทัด
   เดียวกัน แล้วให้ h1/deck กินเต็มความกว้างเพื่อบังคับขึ้นบรรทัดใหม่ */
.auth-header{display:flex;flex-wrap:wrap;align-items:center;text-align:left;margin:0 0 26px;padding-bottom:22px;border-bottom:1px solid var(--line)}

/* ไอคอนหัวข้อ — เลิกเป็นแบดจ์ดำ 44px กลายเป็นตัวเดียวในบรรทัด kicker
   ขีดนำหน้าย้ายมาไว้ที่ตัวมันเอง แล้วปิดขีดของ .auth-subtitle ไม่ให้ซ้ำ
   (.auth-icon ~ .auth-subtitle:before = 0,2,1 ชนะ .auth-subtitle:before = 0,1,1) */
.auth-icon{order:-2;width:auto;height:auto;margin:0 7px 13px 0;padding:0;border-radius:0;background:none;color:var(--ink);font-size:12px;line-height:1;box-shadow:none}
.auth-icon:before{content:'';flex:0 0 auto;width:20px;height:2px;margin-right:8px;background:var(--ink)}
.auth-icon ~ .auth-subtitle:before{display:none}
.auth-icon.warn{color:var(--warning)}
.auth-icon.line{color:#06C755}
.auth-subtitle{order:-1;display:inline-flex;align-items:center;gap:8px;margin:0 0 13px;font-size:10px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.auth-subtitle:before{content:'';flex:0 0 auto;width:20px;height:2px;background:var(--ink)}
.auth-title{flex:0 0 100%;font-size:clamp(30px,4.6vw,50px);font-weight:500;line-height:1;letter-spacing:-.05em;margin:0}
.auth-intro{flex:0 0 100%;margin:13px 0 0;font-size:13px;line-height:1.75}

/* stepper — แถวตัวอักษรเล็ก ไม่ใช่ชิป */
.auth-stepper{margin:0 0 22px;font-size:9.5px;letter-spacing:.12em;text-transform:uppercase}
.auth-stepper i{font-size:11px}
.auth-step.current{font-weight:500;color:var(--ink)}

/* ฟอร์ม — เส้นใต้แทนกล่อง */
.auth-form{gap:22px}
.auth-field label{margin-bottom:2px;font-size:9.5px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.auth-field label i{margin-right:6px;font-size:11px}
.auth-field input,.auth-field select,.auth-field textarea{min-height:44px;padding:0;border:0;border-bottom:1px solid var(--line);border-radius:0;font-size:15px;transition:border-color .16s}
.auth-field textarea{padding:10px 0}
.auth-field input:focus,.auth-field select:focus,.auth-field textarea:focus{border-color:var(--ink)}
.auth-field input:disabled{background:transparent;color:var(--muted)}
.auth-field-input-wrap .field-icon{left:0;font-size:14px}
.auth-field-input-wrap input{padding-left:25px}
.auth-hint{margin-top:7px;font-size:11px}
.auth-hint i{margin-right:5px}

/* OTP — 6 เส้นใต้ ไม่ใช่ 6 กล่อง (.auth-field .otp-box = 0,2,0 ชนะ
   .auth-field input = 0,1,1 ได้โดยไม่ต้องใช้ !important) */
.auth-field .otp-boxes{justify-content:flex-start;gap:10px}
.auth-field .otp-box{width:44px;height:54px;border:0;border-bottom:2px solid var(--line);border-radius:0;font-size:24px;font-weight:300}
.auth-field .otp-box:focus{border-color:var(--ink)}

/* ปุ่ม */
.auth-btn{min-height:50px;font-size:12.5px}
.auth-btn-sc{border-color:var(--line)}
.auth-linkbtn{padding:0;border:0;background:none;color:var(--ink);font-family:inherit;font-size:12.5px;font-weight:500;text-decoration:underline;text-underline-offset:3px;cursor:pointer}

/* LINE — เดิมเป็น inline style ในไฟล์ view ซึ่ง stylesheet ชนะไม่ได้
   ย้ายมาเป็นคลาสที่นี่ แล้วตัด inline ออกจาก view */
.auth-line{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;min-height:50px;margin:0 0 16px;border-radius:999px;background:#06C755;color:#fff;font-size:13px;font-weight:500;transition:background .16s}
.auth-line:hover{background:#05a548}
.auth-line i{font-size:20px}
.auth-line-sc{background:transparent;color:var(--ink);border:1px solid var(--line)}
.auth-line-sc:hover{background:transparent;border-color:var(--ink)}
.auth-or{display:flex;align-items:center;gap:12px;margin:0 0 20px;color:var(--muted);font-size:9.5px;letter-spacing:.12em;text-transform:uppercase}
.auth-or:before,.auth-or:after{content:'';flex:1;height:1px;background:var(--line)}
.auth-note{display:flex;gap:13px;margin:0 0 20px;padding:16px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);font-size:12.5px;line-height:1.7}
.auth-note i{flex:0 0 auto;font-size:16px;color:#06C755;line-height:1.4}
.auth-note b{font-weight:500}
.auth-note.warn i{color:var(--warning)}
.auth-idcard{display:flex;align-items:center;gap:11px;font-size:12px;color:var(--muted)}
.auth-idcard img{width:34px;height:34px;border-radius:50%;object-fit:cover}
.auth-idcard strong{display:block;color:var(--ink);font-weight:500}
.auth-idcard code{font-size:10px}

/* footer */
.auth-footer{text-align:left;margin-top:26px;padding-top:18px;border-top:1px solid var(--line);font-size:12.5px}

@media(max-width:640px){
  .auth-wrap{width:min(calc(100% - 24px),540px);padding:32px 0 56px}
  .auth-field .otp-box{width:38px;height:48px;font-size:20px}
}

/* v-blockimg — content-block images (partials/blocks/image.php + gallery.php)
   had no forced ratio at all: a portrait upload rendered tall, a landscape one
   rendered short, so a row of gallery images never lined up. Every crop in
   this project is meant to be 4:5 (see cover_portrait's own comment in the
   posts migration) — this makes the article body match that everywhere a
   block image shows, and marks them clickable so the crop isn't the only way
   to see the shot. */
.na-content figure img,.article-body figure img{width:100%;aspect-ratio:4/5;object-fit:cover;cursor:zoom-in}
[data-lightbox]{cursor:zoom-in}

/* v-lightbox — click-to-enlarge for the images above. Built once in app.js
   and appended to <body> on first use rather than living in a partial, so it
   doesn't need a place in every layout that can render a block image. */
.img-lightbox{
  position:fixed;inset:0;z-index:200;display:none;
  align-items:center;justify-content:center;padding:26px;
  background:rgba(15,15,15,.92);
  opacity:0;transition:opacity .18s;
}
.img-lightbox.active{display:flex;opacity:1}
.img-lightbox img{
  display:block;max-width:100%;max-height:100%;width:auto;height:auto;
  border-radius:10px;object-fit:contain;background:#111;
  transform:scale(.97);transition:transform .18s;
}
.img-lightbox.active img{transform:none}
.img-lightbox-close{
  position:absolute;top:18px;right:18px;width:42px;height:42px;
  border:1px solid rgba(255,255,255,.3);border-radius:50%;background:rgba(255,255,255,.08);
  color:#fff;font-size:16px;display:grid;place-items:center;cursor:pointer;
}
.img-lightbox-close:hover{background:rgba(255,255,255,.18)}
@media(prefers-reduced-motion: reduce){
  .img-lightbox,.img-lightbox img{transition:none}
}

/* v-nosubnav — mobile already has the bottom tab bar + "ALL MENU" sheet
   (v-mobilenav, same ≤768px breakpoint) covering every link the subnav row
   holds, so the row was a second, redundant nav eating space above the fold
   on top of the header. */
@media(max-width:768px){
  .subnav{display:none}
}

/* v-heroside — .article-hero at 4:5 across the full 1640px page width made
   the crop absurdly tall (~2050px). Every portrait cover in this project is
   meant to sit next to the title instead of stacking full-bleed below it —
   that's what /news/{id}'s own header (.na-header-grid) already does — so
   this brings article.php's header in line with that rather than shrinking
   the crop back to landscape. article.php sets .has-cover on the grid only
   when there's a cover to show; without one it stays a single column. */
.article-head-grid{grid-template-columns:1fr;align-items:start}
.article-head-grid.has-cover{display:grid;grid-template-columns:minmax(0,1fr) minmax(260px,420px);gap:40px}
.article-head-text .byline{border-top:1px solid var(--line);padding-top:14px;margin-top:18px}
/* Desktop/tablet only — ≤640px keeps its own full-bleed .article-hero rule
   (width:100%, border-radius:0) from the base layer, which this must not
   fight: a later unconditional rule would win at every width, mobile
   included, and silently round corners meant to stay square. */
@media(min-width:641px){
  .article-hero{width:100%;margin:0;border-radius:var(--r)}
}
@media(max-width:900px){
  .article-head-grid.has-cover{grid-template-columns:1fr}
}

/* v-buyblock — "buy" content block (partials/blocks/buy.php).
   Affiliate purchase buttons inside an article body: one product summary plus
   a row of external shop buttons (Shopee / Lazada / TikTok Shop / brand site).
   Deliberately NOT reusing .pblock: that one is a single link to our own store
   product, this one is a container holding several links, so the whole card
   cannot be an <a>. Shop brand colours appear on the icon only — the buttons
   stay monochrome like the rest of the page. */
.buyblock{
  margin:34px 0;padding:18px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--paper);display:grid;gap:14px;
}
.buyblock-top{display:grid;grid-template-columns:auto 1fr;align-items:center;gap:16px}
.buyblock-top:only-child{grid-template-columns:1fr}
.buyblock-media{width:92px;height:92px;border-radius:10px;overflow:hidden;flex:0 0 auto;background:#f4f4f4}
.buyblock-media img{width:100%;height:100%;object-fit:cover;display:block}
.buyblock-body{display:grid;gap:6px;min-width:0}
.buyblock-kicker{font-size:9px;font-weight:600;letter-spacing:.14em;color:var(--muted);text-transform:uppercase}
.buyblock-kicker i{font-size:11px;margin-right:4px;vertical-align:-1px}
.buyblock-name{font-size:17px;font-weight:500;letter-spacing:-.03em;line-height:1.28;color:var(--ink)}
.buyblock-meta{font-size:13px;color:var(--muted);line-height:1.5}
.buyblock-meta b{font-weight:500;color:var(--ink)}
.buyblock-links{display:flex;flex-wrap:wrap;gap:9px}
.buyblock-btn{
  display:inline-flex;align-items:center;gap:8px;flex:1 1 190px;
  padding:12px 15px;border:1px solid var(--line);border-radius:10px;
  background:var(--paper);color:var(--ink);font-size:13px;font-weight:500;
  letter-spacing:-.01em;line-height:1.2;text-decoration:none;
  transition:border-color .18s,background .18s,transform .18s;
}
.buyblock-btn:hover{border-color:var(--ink);background:#fafafa;transform:translateY(-1px)}
.buyblock-btn-icon{font-size:15px;flex:0 0 auto}
.buyblock-btn-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.buyblock-btn-price{font-size:12px;color:var(--muted);flex:0 0 auto}
.buyblock-btn-out{font-size:11px;color:var(--muted);flex:0 0 auto;transition:color .18s}
.buyblock-btn:hover .buyblock-btn-out{color:var(--ink)}
.buyblock-disc{font-size:10.5px;color:var(--muted);line-height:1.55}

@media(max-width:640px){
  .buyblock{padding:14px;gap:12px}
  .buyblock-top{gap:12px}
  .buyblock-media{width:70px;height:70px}
  .buyblock-name{font-size:15px}
  .buyblock-btn{flex:1 1 100%;padding:11px 13px}
}

@media (prefers-reduced-motion:reduce){
  .buyblock-btn,.buyblock-btn-out{transition:none}
  .buyblock-btn:hover{transform:none}
}

/* v-herogap — ช่องว่างใต้ byline ในหน้า /news/{id} และ /{หมวด}/{slug}
   .article-head-grid.has-cover เป็น grid 2 คอลัมน์ · แถวสูงเท่ารูปปกเสมอ
   ปกแนวตั้ง 4:5 ในคอลัมน์กว้าง 420px = สูง ~525px แต่ข้อความ (หัวข้อ+byline)
   สูงแค่ ~250px → เหลือรูโหว่ใต้ byline ~275px ก่อนเข้าเนื้อบทความ
   แก้โดยดันข้อความไปชิดล่างให้ก้น byline เสมอกับก้นรูป ที่ว่างที่เหลือจึงไป
   อยู่เหนือหัวข้อซึ่งอ่านเป็น breathing room ไม่ใช่ช่องโหว่
   💡 เคยลองจำกัดความสูงปกด้วย max-height ด้วย แต่มันครอปรูปจน 4:5 เพี้ยน
      จึงถอดออก (ดู v-heroshape ล่างสุด) — ช่องว่างที่เหลือคุมด้วย v-herogap-b */
.article-head-grid.has-cover{align-items:end}
/* บทความที่ไม่มีปกไม่ได้รับผลอะไร — คอลัมน์เดียวอยู่แล้ว */
@media(max-width:900px){
  .article-head-grid.has-cover{align-items:start}
}

/* v-herogap-b — ดันเนื้อบทความขึ้นไปชิดเส้นใต้ byline
   หลัง v-herogap ปกไม่ตั้งเกินข้อความแล้ว แต่ยังเหลือช่องว่างสะสมอีก ~100px
   จาก 3 ที่ที่บวกกันเงียบ ๆ: .article-head padding-bottom 26 + .article-layout
   padding-top 40 + margin-top ของบล็อกแรกในเนื้อหา (การ์ด .buyblock มี 34)
   ตัดทั้งสามให้เหลือระยะหายใจพอดี เนื้อหาจึงเริ่มใต้ byline ทันที
   ⚠️ กระทบหน้าบทความทุกหน้าที่ใช้ article.php (ทั้งที่มีปกและไม่มีปก) */
.article-head{padding-bottom:8px}
.article-layout{padding-top:12px}
/* บล็อกแรกไม่ต้องมีระยะบน — ระยะห่างจาก byline คุมจาก 2 บรรทัดข้างบนแทน */
.article-body > *:first-child{margin-top:0}
@media(max-width:900px){
  /* มือถือคอลัมน์เดียว: ปกอยู่ใต้หัวข้อ ต้องมีระยะคั่นก่อนเข้าเนื้อหา */
  .article-head{padding-bottom:18px}
  .article-layout{padding-top:22px}
}

/* v-heroshape — ปกบทความต้องเป็น 4:5 แนวตั้ง "เสมอ" ทุกขนาดจอ
   1) ยกเลิก max-height ที่ v-herogap ใส่ไว้: มันครอปรูปบน-ล่างจนสัดส่วนจริง
      กลายเป็นเกือบจัตุรัส (420×430) แทนที่จะเป็น 4:5 · ช่องว่างใต้ byline
      ที่เคยแก้ด้วย cap ตอนนี้ v-herogap-b คุมด้วยระยะ padding แทนแล้ว
   2) มือถือ ≤640px เดิมตั้งใจให้ full-bleed ขอบเหลี่ยม (width:100%,
      border-radius:0 ใน base) — เปลี่ยนให้เหมือนเดสก์ท็อป คือมุมมน var(--r)
      และเว้นขอบจอตาม .container (hero อยู่ใน .container อยู่แล้ว) */
.article-head-grid.has-cover .article-hero img{max-height:none}
.article-hero img{aspect-ratio:4/5;height:auto;object-fit:cover}

@media(max-width:640px){
  .article-hero{width:100%;margin:0;border-radius:var(--r);overflow:hidden}
  .article-hero img{aspect-ratio:4/5;max-height:none}
}

/* v-footer — footer: ไอคอนทุกลิงก์ + พับเป็น accordion บนมือถือ
   เดิม: 4 คอลัมน์ลิงก์เปล่า ๆ ยาว 4-6 บรรทัด พอจอแคบกลายเป็นลิสต์ยาวรก
   ตอนนี้: หัวข้อแต่ละคอลัมน์เป็นปุ่ม (.foot-head) มีไอคอนนำ + ลูกศร
     >768px  ลูกศรซ่อน ลิงก์กางอยู่แล้ว ปุ่มกดแล้วไม่มีผล (cursor:default)
     ≤768px  พับทุกคอลัมน์ กดหัวข้อเพื่อกาง — .open ใส่โดย app.js
   ⚠️ .footer .foot-links a ต้องมี .footer นำหน้าเพื่อให้ specificity เท่า
      .footer a:not(.brand) ที่ตั้ง display:block ไว้ตั้งแต่ base แล้วชนะด้วยลำดับ */
.foot-title{margin:0}
.foot-head{display:flex;align-items:center;gap:9px;width:100%;padding:0;border:0;background:0;
  color:#8d9097;font-size:10px;font-weight:500;letter-spacing:.14em;text-align:left;cursor:default}
.foot-head-icon{font-size:13px;line-height:1;color:#6f7278}
.foot-caret{display:none;margin-left:auto;transition:transform .25s ease}
.footer .foot-links{display:grid;gap:1px;margin-top:12px}
.footer .foot-links a{display:flex;align-items:center;gap:10px;margin:0;padding:5px 0;
  font-size:12.5px;color:#d9dbdf;transition:color .2s ease,transform .2s ease}
.footer .foot-links a i{width:16px;font-size:14px;line-height:1;color:#7e8188;transition:color .2s ease}
.footer .foot-links a:hover{color:#fff;transform:translateX(2px)}
.footer .foot-links a:hover i{color:#fff}

@media(max-width:768px){
  .footer{padding:36px 0 20px}
  .footer-grid{grid-template-columns:1fr;gap:0}
  .footer-intro{padding-bottom:20px}
  .foot-col{border-top:1px solid rgba(255,255,255,.12)}
  .foot-col:last-of-type{border-bottom:1px solid rgba(255,255,255,.12)}
  .footer .foot-head{padding:16px 2px;color:#fff;font-size:11px;cursor:pointer}
  .foot-head-icon{font-size:15px;color:#9a9da4}
  .foot-caret{display:block;font-size:12px;color:#8d9097}
  .foot-col.open .foot-caret{transform:rotate(180deg)}
  .footer .foot-col:not(.open) .foot-links{display:none}
  .footer .foot-col .foot-links{margin:0 0 14px;padding-left:24px;gap:2px}
  .footer .foot-col .foot-links a{padding:7px 0}
  .foot-col.open .foot-links{animation:footSlide .26s ease both}
}
@keyframes footSlide{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
@media(prefers-reduced-motion:reduce){
  .foot-col .foot-links{animation:none}
  .foot-caret{transition:none}
  .footer .foot-links a{transition:none}
  .footer .foot-links a:hover{transform:none}
}

/* v-cathome — หน้าแรก: "ทุกหมวด" (HomeController kind='categories')
   ทุกหมวดใน `categories` + ข่าวต่างประเทศ ถูกดึงมาโชว์เป็น rail ละหมวด

   กฎที่สำคัญที่สุดของ layer นี้: กริดต้องสูง "2 แถวเป๊ะ" ทุกขนาดจอ
   จึงประกาศจำนวนคอลัมน์เป็นตัวเลขตายตัว (5/4/3/2) ทุก breakpoint ไม่ใช้
   auto-fit — เพราะจุดตัด nth-child ด้านล่างต้องรู้แน่ว่าแถวที่ 3 เริ่มที่ใบไหน
   (auto-fit ทำให้จำนวนคอลัมน์เปลี่ยนตามความกว้าง จุดตัดจะเพี้ยนทันที)

     5 คอลัมน์ -> ตัดที่ใบ 11   4 -> ใบ 9   3 -> ใบ 7   2 -> ใบ 5
   controller ดึงมา 10 ใบ (source.limit) ใบที่เกินของจอนั้นถูกซ่อน ไม่ใช่ตัดทิ้ง
   จอกว้างขึ้นจึงได้ครบ 2 แถวเสมอโดยไม่ต้องยิง request ใหม่

   ไม่มี !important ใหม่: การ์ดที่นี่ไม่มี inline display เหมือนต้นแบบ
   (ต้นแบบต้องใช้ !important เพราะการ์ดถูกเซ็ต display:block ไว้ใน markup)

   ค่าที่ไล่ตามขนาดจอแบบต่อเนื่อง (padding / font-size / ระยะห่าง) ใช้ clamp()
   ไม่ประกาศ selector ซ้ำใน @media — เหลือไว้เฉพาะสิ่งที่ clamp ทำแทนไม่ได้
   คือจำนวนคอลัมน์กับจุดตัด 2 แถว (ดู rule css-debt ใน scripts/check.php)

   หมายเหตุ: ห้ามใช้ .hp-card:before ทำอย่างอื่น — data-glare (layer v-motion)
   จอง pseudo ตัวนั้นไว้ทำแสงกวาดแล้ว ความสูง 4:5 จึงอยู่ที่ตัว .hp-card เอง */
.hp-rails{padding-bottom:26px}
.hp-rails .hp-rail{margin-top:clamp(34px,3.6vw,44px)}
/* rail แรกไม่มีหัวข้อของ block คั่นอยู่ข้างบนแล้ว — padding ของ .section พอ */
.hp-rails .hp-rail:first-child{margin-top:0}

/* header sticky ทับหัวข้อตอนลิงก์เข้า #cat-{slug} มาจากที่อื่น */
.hp-rail{scroll-margin-top:clamp(88px,9vw,120px)}
.hp-rail-head{margin-bottom:20px;padding-bottom:13px}
.hp-rail-title{font-size:clamp(19px,1.8vw,25px);letter-spacing:-.03em;margin:6px 0 0;font-weight:400;color:var(--muted)}

.hp-grid{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:clamp(10px,1.1vw,14px)}
.hp-grid > a:nth-child(n+11){display:none}

.hp-card{position:relative;display:block;aspect-ratio:4/5;border-radius:14px;overflow:hidden;
  background:#161616;border:1px solid var(--line);
  transition:transform .25s ease,box-shadow .25s ease,border-color .25s ease}
.hp-card img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  transition:transform .45s cubic-bezier(.22,.61,.36,1)}
.hp-card:hover{transform:translateY(-3px);border-color:var(--ink);box-shadow:0 14px 34px rgba(0,0,0,.18)}
.hp-card:hover img{transform:scale(1.04)}
.hp-card:after{content:'';position:absolute;inset:0;
  background:linear-gradient(180deg,rgba(0,0,0,0) 32%,rgba(0,0,0,.9) 100%)}

.hpc-body{position:absolute;inset:0;z-index:3;display:flex;flex-direction:column;
  justify-content:flex-end;gap:clamp(6px,.7vw,7px);
  padding:clamp(12px,1.2vw,15px) clamp(13px,1.3vw,16px);color:#fff}
.hpc-cat{align-self:flex-start;padding:4px 9px;border-radius:5px;
  background:rgba(255,255,255,.92);color:#0f0f0f;
  font-size:9px;font-weight:600;letter-spacing:.12em;line-height:1.4}
.hpc-title{margin:0;font-size:clamp(13px,1.05vw,14px);font-weight:500;line-height:1.36;
  letter-spacing:-.02em;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.hpc-meta{display:flex;flex-wrap:wrap;gap:10px;font-size:10px;color:rgba(255,255,255,.72)}

/* จุดตัด 2 แถว — ตัวเลขคอลัมน์กับ nth-child ต้องเปลี่ยนคู่กันเสมอ */
@media(max-width:1160px){
  .hp-grid{grid-template-columns:repeat(4,minmax(0,1fr))}
  .hp-grid > a:nth-child(n+9){display:none}
}
@media(max-width:900px){
  .hp-grid{grid-template-columns:repeat(3,minmax(0,1fr))}
  .hp-grid > a:nth-child(n+7){display:none}
}
@media(max-width:640px){
  .hp-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .hp-grid > a:nth-child(n+5){display:none}
}

@media(prefers-reduced-motion:reduce){
  .hp-card,.hp-card img{transition:none}
  .hp-card:hover,.hp-card:hover img{transform:none}
}

/* v-shopping — /shopping + /shopping/{slug} (curated affiliate products,
   2026-08-29). The grid reuses .card-grid/.story as-is (same shell as
   public/rankings.php) and the product page reuses .buyblock/.buyblock-btn
   as-is (partials/blocks/buy.php) — only the bits neither of those already
   covers are declared here: category filter chips + the price tag on a
   grid card. Deliberately small: this whole layer is additive, no existing
   selector from v-buyblock/v-cathome/base is redeclared. */
.shp-filters{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:22px}
.shp-chip{padding:8px 15px;border:1px solid var(--line);border-radius:999px;
  font-size:12px;font-weight:500;letter-spacing:.02em;color:var(--muted);
  background:var(--paper);text-decoration:none;transition:border-color .16s,color .16s,background .16s}
.shp-chip:hover{border-color:var(--ink);color:var(--ink)}
.shp-chip.active{background:var(--ink);border-color:var(--ink);color:#fff}

.shp-card .story-media{position:relative}
.shp-featured{position:absolute;top:10px;left:10px;padding:4px 9px;border-radius:5px;
  background:rgba(255,255,255,.94);color:#0f0f0f;font-size:9px;font-weight:600;letter-spacing:.1em}
.shp-price{display:block;margin-top:4px;font-size:13px;font-weight:500;color:var(--ink)}

.shp-detail{margin:0}
.shp-detail-media{width:120px;height:120px}
.shp-desc{margin:2px 0 4px;font-size:14px;line-height:1.7;color:var(--ink)}

@media(max-width:640px){
  .shp-detail-media{width:84px;height:84px}
}
