/* AsoTheory: Blueprint-inspired theme (Palantir Foundry aesthetic), light + dark */

:root{
  --bg:#F6F7F9;
  --panel:#fff;
  --panel-alt:#FAFBFC;
  --line:#E1E5EA;
  --line-strong:#C5CBD3;
  --tx:#1C2127;
  --tx-2:#5F6B7C;
  --tx-3:#8F99A8;
  --blue:#2D72D2;
  --blue-hover:#215DB0;
  --blue-tint:#EAF2FC;
  --blue-line:#C6DBF5;
  --star:#D9911B;
  --green:#1C6E42;
  --green-tint:#E7F5EC;
  --green-line:#BFE0CC;
  --orange:#935610;
  --orange-tint:#FDF0E1;
  --orange-line:#F2D4AF;
  --red:#AC2F33;
  --red-tint:#FBEAEA;
  --red-line:#EDC4C5;

  --btn-bg:linear-gradient(180deg,#fff,#F6F7F9);
  --btn-bg-hover:linear-gradient(180deg,#F6F7F9,#EDEFF2);
  --btn-active:#E5E8EB;
  --btn-line-hover:#AFB8C1;
  --inset:inset 0 1px 1px rgba(17,20,24,.06);
  --drop:0 1px 1px rgba(17,20,24,.06);
  --pop:0 4px 12px rgba(17,20,24,.15);
  --diff-old-bg:#FDF3F3; --diff-old-tx:#8E292C;
  --diff-new-bg:#F1FAF4; --diff-new-tx:#165A36;
  --toast-bg:#1C2127; --toast-tx:#fff;
  --dot-med:#C87619;
  --img-line:#E1E5EA;

  --r:3px;
  --r-sm:2px;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;
  color-scheme:light;
}

[data-theme="dark"]{
  --bg:#171B21;
  --panel:#20252C;
  --panel-alt:#262C34;
  --line:#333B45;
  --line-strong:#454F5C;
  --tx:#EDF0F4;
  --tx-2:#A7B0BC;
  --tx-3:#7D8794;
  --blue:#4C90F0;
  --blue-hover:#8ABBFF;
  --blue-tint:#1B3252;
  --blue-line:#2C4C79;
  --star:#FFC53D;
  --green:#72CA9B;
  --green-tint:#17362A;
  --green-line:#2A5842;
  --orange:#FBB360;
  --orange-tint:#3A2C1A;
  --orange-line:#5E4526;
  --red:#FA999C;
  --red-tint:#3B2124;
  --red-line:#5E3438;

  --btn-bg:linear-gradient(180deg,#2B313A,#252A31);
  --btn-bg-hover:linear-gradient(180deg,#333A44,#2C323A);
  --btn-active:#1E232A;
  --btn-line-hover:#5A6573;
  --inset:inset 0 1px 1px rgba(0,0,0,.35);
  --drop:0 1px 1px rgba(0,0,0,.3);
  --pop:0 6px 18px rgba(0,0,0,.5);
  --diff-old-bg:#3A2225; --diff-old-tx:#FCB8BA;
  --diff-new-bg:#17362A; --diff-new-tx:#8FDCB4;
  --toast-bg:#EDF0F4; --toast-tx:#171B21;
  --dot-med:#FBB360;
  --img-line:#3D4650;
  color-scheme:dark;
}

*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:var(--bg); color:var(--tx);
  font:17px/1.55 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,sans-serif;
  -webkit-font-smoothing:antialiased;
}
.hidden{display:none !important}
.muted{color:var(--tx-2)} .small{font-size:15px} .tiny{font-size:14px}
.mono{font-family:var(--mono);font-size:15px}
a{color:var(--blue);text-decoration:none} a:hover{text-decoration:underline}
h1{font-size:26px;font-weight:600;letter-spacing:-.01em}
h2{font-size:18px;font-weight:600}
h3{font-size:16px;font-weight:600}
/* A tinted box behind every img, so an app icon that is still loading or has a
   dead URL leaves a placeholder rather than a hole. It must not apply to the
   store marks: those are transparent PNGs, and in dark mode --panel-alt is a
   near-black, which showed through the empty corners of the Google Play triangle
   as a black rounded square. The App Store mark hid the same bug by being 96%
   opaque, which is why only one of the two looked wrong. */
img:not(.store-mark){background:var(--panel-alt)}

/* ------------------------------------------------ buttons */
.btn{
  font:inherit;font-size:16px;font-weight:400;cursor:pointer;
  border-radius:var(--r-sm);border:1px solid var(--line-strong);
  background:var(--btn-bg);color:var(--tx);
  padding:5px 11px;display:inline-flex;align-items:center;gap:6px;
  box-shadow:var(--drop);
}
.btn:hover{background:var(--btn-bg-hover);border-color:var(--btn-line-hover)}
.btn:active{background:var(--btn-active);box-shadow:none}
.btn.primary{background:var(--blue);border-color:var(--blue);color:#fff}
[data-theme="dark"] .btn.primary{color:#0E1319}
.btn.primary:hover{background:var(--blue-hover);border-color:var(--blue-hover)}
.btn.minimal{background:none;border-color:transparent;box-shadow:none;color:var(--blue)}
.btn.minimal:hover{background:var(--blue-tint);border-color:transparent}
.btn.small{padding:3px 8px;font-size:15px}
.btn.block{width:100%;justify-content:center;padding:7px}
.btn.danger{color:var(--red)}
.btn.danger:hover{background:var(--red-tint)}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn.icon{padding:4px 8px;font-size:16px;line-height:1.2}
.th-moon{display:none}
[data-theme="dark"] .th-moon{display:inline}
[data-theme="dark"] .th-sun{display:none}

/* ------------------------------------------------ auth */
.auth-wrap{min-height:100vh;display:grid;place-items:center;padding:24px;background:var(--bg)}
.auth-card{width:100%;max-width:360px;background:var(--panel);border:1px solid var(--line);
  border-radius:var(--r);padding:26px;box-shadow:var(--pop)}
.auth-top{display:flex;align-items:center;justify-content:space-between;gap:10px}
.auth-tag{color:var(--tx-2);font-size:16px;margin:8px 0 20px}
.seg{display:flex;border:1px solid var(--line-strong);border-radius:var(--r-sm);overflow:hidden;margin-bottom:18px}
.seg-btn{flex:1;background:var(--btn-bg);border:0;border-right:1px solid var(--line);
  color:var(--tx-2);font:inherit;font-size:16px;padding:6px;cursor:pointer}
.seg-btn:last-child{border-right:0}
.seg-btn.active{background:var(--blue);color:#fff}
[data-theme="dark"] .seg-btn.active{color:#0E1319}
.seg.compact{margin-bottom:0;flex-shrink:0}
.seg.compact .seg-btn{padding:5px 11px;font-size:15px;white-space:nowrap}
.tag svg{vertical-align:-2px}
label{display:block;font-size:15px;color:var(--tx-2);margin-bottom:13px;font-weight:500}
input,select{
  width:100%;margin-top:4px;background:var(--panel);border:1px solid var(--line-strong);
  color:var(--tx);border-radius:var(--r-sm);padding:6px 9px;font:inherit;font-size:16px;
  box-shadow:var(--inset);
}
input:focus,select:focus{outline:none;border-color:var(--blue);box-shadow:0 0 0 2px var(--blue-tint)}
input::placeholder{color:var(--tx-3)}
.err{background:var(--red-tint);border:1px solid var(--red-line);color:var(--red);font-size:15px;
  padding:7px 9px;border-radius:var(--r-sm);margin-bottom:11px}
.divider{display:flex;align-items:center;gap:10px;margin:16px 0;color:var(--tx-3);font-size:14px}
.divider:before,.divider:after{content:"";flex:1;height:1px;background:var(--line)}

/* ------------------------------------------------ top bar */
.topbar{
  height:54px;background:var(--panel);border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:16px;padding:0 14px;position:sticky;top:0;z-index:40;
}
.brand{display:flex;align-items:center;gap:9px;font-size:18px;font-weight:600;cursor:pointer;
  padding-right:14px;border-right:1px solid var(--line);height:100%;color:var(--tx)}
.brand:hover{text-decoration:none}
/* The real logo, replacing the letter-A badge, so the dashboard and the
   marketing site carry the same mark.

   `background:none` is required, not tidiness: the artwork is a dark rounded
   square on a transparent field, and the global `img:not(.store-mark)` rule
   twelve lines up would otherwise paint a hard-cornered panel block behind it
   and square off the rounding. That is the same fault that put a black box
   around the Google Play mark. */
.brand .mark{width:24px;height:24px;border-radius:6px;background:none;
  display:block;flex-shrink:0;object-fit:contain}
.omni{position:relative;flex:1;max-width:440px;margin:0 auto}
.omni input{margin-top:0;padding-left:28px;background:var(--panel-alt)}
.omni .mag{position:absolute;left:9px;top:50%;transform:translateY(-50%);color:var(--tx-3);font-size:15px}
.topbar-right{margin-left:auto;display:flex;align-items:center;gap:10px}
.search-results{
  position:absolute;top:calc(100% + 4px);left:0;right:0;max-height:420px;overflow:auto;
  background:var(--panel);border:1px solid var(--line-strong);border-radius:var(--r);
  box-shadow:var(--pop);z-index:50;
}
.sr-item{display:flex;align-items:center;gap:10px;padding:7px 10px;cursor:pointer;
  border-bottom:1px solid var(--line)}
.sr-item:last-child{border-bottom:0}
.sr-item:hover{background:var(--blue-tint)}
.sr-item img{width:30px;height:30px;border-radius:var(--r-sm);flex-shrink:0;border:1px solid var(--img-line)}
.sr-meta{min-width:0;flex:1}
.sr-name{font-size:16px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ------------------------------------------------ shell */
.shell{display:flex;min-height:calc(100vh - 54px)}
.sidebar{width:266px;flex-shrink:0;background:var(--panel);border-right:1px solid var(--line);
  padding:10px 0;position:sticky;top:54px;height:calc(100vh - 54px);overflow-y:auto}
.side-back{display:flex;align-items:center;gap:8px;padding:8px 14px;color:var(--tx-2);font-size:16px;
  cursor:pointer;border-bottom:1px solid var(--line);margin-bottom:2px}
.side-back:hover{color:var(--tx)}
.side-entity{display:flex;align-items:center;gap:10px;padding:12px 14px;border-bottom:1px solid var(--line);
  margin-bottom:8px}
.side-entity img{width:28px;height:28px;border-radius:var(--r-sm);border:1px solid var(--img-line)}
.side-entity .se-name{font-size:16px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.side-nav{padding:0 8px}
.nav-item{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--r);
  color:var(--tx);font-size:16px;cursor:pointer;margin-bottom:1px;border:1px solid transparent}
.nav-item:hover{background:var(--panel-alt)}
.nav-item.active{background:var(--blue-tint);border-color:var(--blue-line);font-weight:500}
.nav-item .ic{color:var(--tx-2);display:flex;flex-shrink:0}
.nav-item.active .ic{color:var(--blue)}
.nav-count{margin-left:auto;font-size:14px;color:var(--tx-3);background:var(--bg);
  padding:0 5px;border-radius:8px;line-height:16px}
.side-label{font-size:13px;text-transform:uppercase;letter-spacing:.06em;color:var(--tx-3);
  padding:12px 17px 5px;font-weight:600}

.main{flex:1;min-width:0;padding:20px 24px 60px;max-width:1280px}

/* ------------------------------------------------ entity header */
.ent-head{display:flex;align-items:flex-start;gap:12px;margin-bottom:16px}
.ent-icon{width:38px;height:38px;border-radius:var(--r);border:1px dashed var(--line-strong);
  display:grid;place-items:center;background:var(--panel);flex-shrink:0;overflow:hidden;color:var(--tx-2)}
.ent-icon img{width:100%;height:100%;object-fit:cover}
/* The app's own logo, in the detail header only. Sized to span the title and the
   line under it rather than just the title: at 38px it sat against the 26px name
   and left the developer line hanging off the bottom unbalanced. 52px is title
   (26px at 1.2 line-height) plus subtitle (15px) plus the 1px gap between them.
   Scoped with a modifier so the section headers that use `.ent-icon` for a plain
   glyph keep their smaller badge. */
.ent-icon.lg{width:52px;height:52px}
.ent-title{font-size:26px;font-weight:600;letter-spacing:-.01em;line-height:1.2}
.ent-type{font-size:15px;color:var(--tx-2);margin-top:1px}
.ent-actions{margin-left:auto;display:flex;gap:6px;align-items:center;flex-wrap:wrap}

/* ------------------------------------------------ panels */
.panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--r)}
.panel-head{display:flex;align-items:center;gap:8px;padding:9px 13px;border-bottom:1px solid var(--line)}
.panel-head h3{font-size:16px;font-weight:600}
.panel-head .act{margin-left:auto}
.panel-body{padding:13px}
.panel-body.flush{padding:0}
.count{font-size:14px;color:var(--tx-2);background:var(--bg);border:1px solid var(--line);
  padding:0 6px;border-radius:9px;line-height:16px;font-weight:500}

.split{display:grid;grid-template-columns:1fr 340px;gap:0;border:1px solid var(--line);
  border-radius:var(--r);background:var(--panel);margin-bottom:16px;overflow:hidden}
.split-l{padding:18px 20px}
.split-r{border-left:1px solid var(--line);background:var(--panel-alt)}
.split-r .sec{padding:14px 16px;border-bottom:1px solid var(--line)}
.split-r .sec:last-child{border-bottom:0}
.field{display:flex;gap:16px;padding:7px 0;font-size:16px}
.field .k{width:120px;flex-shrink:0;color:var(--tx-2)}
.field .v{flex:1;min-width:0;word-break:break-word}
.kv{display:flex;justify-content:space-between;gap:12px;align-items:center;padding:6px 0;font-size:16px}
.kv .k{color:var(--tx-2)}
.kv .v{text-align:right;font-weight:500}

.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:14px;margin-bottom:14px}

.lrow{display:flex;align-items:center;gap:10px;padding:10px 14px;border-bottom:1px solid var(--line);font-size:16px}
.lrow:last-child{border-bottom:0}
.lrow:hover{background:var(--panel-alt)}
.lrow img{width:20px;height:20px;border-radius:var(--r-sm);border:1px solid var(--img-line)}
.gl{width:18px;height:18px;border-radius:var(--r-sm);display:grid;place-items:center;font-size:13px;
  flex-shrink:0;background:var(--blue-tint);color:var(--blue);border:1px solid var(--blue-line)}
.gl.g{background:var(--green-tint);color:var(--green);border-color:var(--green-line)}
.gl.o{background:var(--orange-tint);color:var(--orange);border-color:var(--orange-line)}
.gl.r{background:var(--red-tint);color:var(--red);border-color:var(--red-line)}
.lrow .rt{margin-left:auto;color:var(--tx-2);font-size:15px;flex-shrink:0}

/* ------------------------------------------------ tags */
.tag{display:inline-block;font-size:14px;font-weight:500;padding:1px 6px;border-radius:var(--r-sm);
  background:var(--bg);color:var(--tx-2);border:1px solid var(--line)}
.tag.blue{background:var(--blue-tint);color:var(--blue);border-color:var(--blue-line)}
.tag.green{background:var(--green-tint);color:var(--green);border-color:var(--green-line)}
.tag.orange{background:var(--orange-tint);color:var(--orange);border-color:var(--orange-line)}
.tag.red{background:var(--red-tint);color:var(--red);border-color:var(--red-line)}
.tag.high{background:var(--red-tint);color:var(--red);border-color:var(--red-line)}
.tag.medium{background:var(--orange-tint);color:var(--orange);border-color:var(--orange-line)}
.tag.low,.tag.info{background:var(--bg);color:var(--tx-2);border-color:var(--line)}
.tag.cc{text-transform:uppercase;font-family:var(--mono);font-size:13px;letter-spacing:.03em}

/* ------------------------------------------------ tables */
table{width:100%;border-collapse:collapse;font-size:16px}
th{text-align:left;color:var(--tx-2);font-weight:500;font-size:14px;text-transform:uppercase;
  letter-spacing:.05em;padding:7px 13px;border-bottom:1px solid var(--line);background:var(--panel-alt)}
td{padding:9px 14px;border-bottom:1px solid var(--line)}
tr:last-child td{border-bottom:0}
tbody tr:hover{background:var(--panel-alt)}
.num{font-family:var(--mono);font-size:15px}
th.r,td.r{text-align:right}
/* The scenario the model is currently applying. */
tbody tr.on{background:var(--sel,rgba(45,114,210,.09))}
tbody tr.on td{border-bottom-color:var(--line)}
tbody tr.on td:first-child{box-shadow:inset 3px 0 0 var(--blue)}

/* ------------------------------------------------ timeline */
.tl{padding:4px 0}
.tl-item{display:flex;gap:12px;padding:11px 13px;border-bottom:1px solid var(--line)}
.tl-item:last-child{border-bottom:0}
.tl-item:hover{background:var(--panel-alt)}
.tl-rail{width:8px;flex-shrink:0;display:flex;justify-content:center;padding-top:4px}
.tl-dot{width:7px;height:7px;border-radius:50%;background:var(--tx-3)}
.tl-item.high .tl-dot{background:var(--red)}
.tl-item.medium .tl-dot{background:var(--dot-med)}
.tl-body{flex:1;min-width:0}
.tl-head{display:flex;align-items:center;gap:7px;flex-wrap:wrap;font-size:16px}
.tl-time{margin-left:auto;color:var(--tx-3);font-size:14px;flex-shrink:0}
.diff{margin-top:6px;border:1px solid var(--line);border-radius:var(--r-sm);overflow:hidden}
.diff-line{font-size:15px;padding:5px 9px;font-family:var(--mono);word-break:break-word;line-height:1.5}
.diff-old{background:var(--diff-old-bg);color:var(--diff-old-tx);border-bottom:1px solid var(--line)}
.diff-new{background:var(--diff-new-bg);color:var(--diff-new-tx)}

/* ------------------------------------------------ misc */
.empty{text-align:center;padding:48px 20px;color:var(--tx-2)}
.empty-mark{width:38px;height:38px;margin:0 auto 10px;border:1px dashed var(--line-strong);
  border-radius:var(--r);display:grid;place-items:center;color:var(--tx-3)}
.chips{display:flex;align-items:center;gap:6px;justify-content:center;margin-top:14px;flex-wrap:wrap}
.stat-big{font-size:32px;font-weight:600;letter-spacing:-.02em;font-variant-numeric:tabular-nums}

/* A row of headline counts above a section. */
.stats-row{display:grid;grid-template-columns:repeat(auto-fit,minmax(120px,1fr));gap:0;
  border:1px solid var(--line);border-radius:6px;background:var(--panel);
  margin-bottom:14px;overflow:hidden}
.stats-row .stat{padding:12px 15px;border-right:1px solid var(--line)}
.stats-row .stat:last-child{border-right:0}
.stats-row .stat .n{font-size:24px;font-weight:600;font-variant-numeric:tabular-nums;
  letter-spacing:-.01em}
.stats-row .stat .l{font-size:12.5px;color:var(--tx-2);margin-top:2px}

/* Rank movement. Up is good on a chart, so green climbs and red falls. */
.mv{font-family:var(--mono);font-size:13px;font-weight:600;white-space:nowrap}
.mv.up{color:var(--green)}
.mv.down{color:var(--red)}
/* Score meters. Both the track and the fill must be block-level: these were
   spans, and a non-replaced inline element ignores width and height, so the fill
   collapsed to nothing and the track read as a hairline. */
.bar-track{display:block;background:var(--bg);border:1px solid var(--line);
  border-radius:999px;width:100%;height:8px;overflow:hidden;padding:0}
.bar{display:block;height:100%;border-radius:999px;background:var(--blue);
  min-width:2px;transition:width .18s ease}

/* A score beside its meter, used in the keyword tables. */
.score{display:inline-flex;align-items:center;gap:9px;white-space:nowrap}
.score .sv{font-family:var(--mono);font-size:15px;font-weight:600;min-width:24px;
  text-align:right;font-variant-numeric:tabular-nums}
.score .bar-track{width:62px;flex-shrink:0}
.score.good .sv{color:var(--green)}
.score.mid  .sv{color:var(--orange)}
.score.bad  .sv{color:var(--red)}
.score.good .bar{background:var(--green)}
.score.mid  .bar{background:var(--orange)}
.score.bad  .bar{background:var(--red)}
.shots{display:flex;gap:9px;overflow-x:auto;padding:13px}
.shots img{height:190px;border-radius:var(--r);border:1px solid var(--img-line)}
.desc-box{white-space:pre-wrap;font-size:16px;line-height:1.6;color:var(--tx-2);
  max-height:300px;overflow:auto;padding:13px}
.note{background:var(--panel-alt);border:1px solid var(--line);border-left:2px solid var(--blue);
  padding:10px 13px;border-radius:var(--r-sm);font-size:15.5px;color:var(--tx-2);margin-top:12px;line-height:1.6}
.note.grey{border-left-color:var(--line-strong)}
.finding{display:flex;gap:9px;padding:9px 13px;border-bottom:1px solid var(--line)}
.finding:last-child{border-bottom:0}
.row-flex{display:flex;gap:8px;align-items:flex-end;flex-wrap:wrap}
.row-flex label{margin-bottom:0;flex:1;min-width:130px}
.spinner{display:inline-block;width:11px;height:11px;border:2px solid var(--line);
  border-top-color:var(--blue);border-radius:50%;animation:spin .7s linear infinite;vertical-align:-1px}
@keyframes spin{to{transform:rotate(360deg)}}
.loading{padding:40px;text-align:center;color:var(--tx-2);font-size:16px}
.toast{position:fixed;bottom:18px;left:50%;transform:translateX(-50%);z-index:99;
  background:var(--toast-bg);color:var(--toast-tx);padding:8px 14px;border-radius:var(--r);
  box-shadow:var(--pop);font-size:16px}
select.inline{width:auto;margin-top:0;padding:4px 8px;font-size:15px}

/* The hamburger only exists below the drawer breakpoint. */
.nav-toggle{display:none;background:none;border:0;color:var(--tx-2);cursor:pointer;
  padding:6px;margin-left:-4px;border-radius:var(--r-sm);align-items:center}
.nav-toggle:hover{background:var(--btn-bg-hover);color:var(--tx)}
.scrim{position:fixed;inset:54px 0 0;background:rgba(0,0,0,.5);z-index:35;
  opacity:0;pointer-events:none;transition:opacity .18s ease}
.scrim.on{opacity:1;pointer-events:auto}

/* The identity block of a list row: name and subtitle, taking the space the
   fixed-width chips beside it do not need. A class rather than an inline style,
   because an inline min-width cannot be overridden by a media query. */
.row-main{flex:1;min-width:0}

/* ------------------------------------------------ narrow layouts

   Below 900px the sidebar used to be display:none, which hid every section of the
   product behind nothing: there was no other way to reach Top charts, Trends or an
   app's panels. It is now an off-canvas drawer instead, so the navigation still
   exists on a phone. */
@media(max-width:900px){
  .nav-toggle{display:flex}
  .sidebar{
    position:fixed;top:54px;left:0;bottom:0;width:270px;max-width:84vw;z-index:36;
    transform:translateX(-100%);transition:transform .2s ease;
    border-right:1px solid var(--line);box-shadow:0 0 40px rgba(0,0,0,.35);
    height:auto;
  }
  .sidebar.open{transform:translateX(0)}
  .split{grid-template-columns:1fr}
  .split-r{border-left:0;border-top:1px solid var(--line)}
  .main{padding:16px 14px 50px}
  .omni{max-width:none;margin:0}
  /* The store switch keeps its logos and drops its words: on a phone the two marks
     are unambiguous and the label is what pushes the search field off screen. */
  #store-switch .seg-btn{padding:5px 9px;font-size:0;gap:0}
  #store-switch .store-mark{margin:0}
  #user-email{display:none}
  .topbar{gap:10px;padding:0 10px}
  .brand-word{display:none}
  .ent-head{flex-wrap:wrap}
  .ent-actions{width:100%;flex-wrap:wrap}
}

/* ------------------------------------------------ phones */
@media(max-width:600px){
  :root{--r:7px}
  body{font-size:16px}
  .main{padding:13px 11px 44px}
  .cards{grid-template-columns:1fr;gap:11px}
  .stats-row{grid-template-columns:repeat(2,1fr)}
  .stats-row .stat{border-right:0;border-bottom:1px solid var(--line)}
  .stats-row .stat:nth-child(odd){border-right:1px solid var(--line)}
  .ent-title{font-size:22px}
  .stat-big{font-size:26px}
  /* Wide tables scroll rather than squeezing columns into unreadable slivers. */
  .panel-body.flush{overflow-x:auto;-webkit-overflow-scrolling:touch}
  table{min-width:560px}
  .legal-table,.stats-row{min-width:0}
  .row-flex{flex-direction:column;align-items:stretch;gap:9px}
  .row-flex label{max-width:none !important}
  .panel-head{flex-wrap:wrap;gap:6px}
  .panel-head .act{margin-left:0;width:100%}
  .rv-b,.th-q{font-size:14px}
  /* Rows built as a single flex line squeeze the app name into three wrapped words
     while chips hold their width. Below 600px the row becomes two lines: identity
     first, then its metadata. */
  .lrow{flex-wrap:wrap;row-gap:7px;padding:11px 12px}
  .lrow > img,.lrow > .comp-ico,.lrow > .gl{flex-shrink:0}
  /* flex:1 alone lets the name shrink to nothing while the chips hold their width.
     Claiming the rest of the first line forces the chips onto line two, which is
     what actually stops the three-word wrap. */
  .lrow > .row-main{flex:1 1 calc(100% - 46px);min-width:calc(100% - 46px)}
  .lrow > .tag,.lrow > .rt,.lrow > .pill,.lrow > .mono{margin-left:0}
  .lrow > .tag:first-of-type{margin-left:38px}
  .lrow .rt{margin-left:auto}
  .feed-row .chev{margin-left:4px}
  .score .bar-track{width:46px}
  .shots img{height:150px}
}

/* ------------------------------------------------ trends */
.trend-row{display:flex;align-items:center;gap:14px;padding:11px 13px;
  border-bottom:1px solid var(--line);cursor:pointer}
.trend-row:hover{background:var(--panel-alt)}
.trend-main{flex:1;min-width:0}
.trend-term{display:flex;align-items:center;gap:7px;font-size:17px;margin-bottom:2px;flex-wrap:wrap}
.trend-spark{flex-shrink:0;line-height:0}
.trend-score{flex-shrink:0;text-align:right;min-width:44px}
.trend-detail{border-bottom:1px solid var(--line);background:var(--panel-alt);padding-top:8px}
.trend-detail .lrow{background:transparent}
.tag.tiny{font-size:13px}
@media(max-width:720px){.trend-spark{display:none}}

/* Shown only when the running server predates the front-end. */
.stale-bar{background:var(--orange-tint);color:var(--orange);border-bottom:1px solid var(--orange-line);
  padding:9px 16px;font-size:16px;line-height:1.5}
.stale-bar .mono{font-family:var(--mono);font-size:15px}

/* ------------------------------------------------ expandable change feed */
.feed-row .chev{color:var(--tx-3);font-size:13px;flex-shrink:0;width:12px;text-align:center}
.feed-detail{padding:0 14px 12px 44px;border-bottom:1px solid var(--line);
  background:var(--panel-alt)}
.feed-detail .diff{margin-top:0}
.feed-meta-row{display:flex;align-items:center;gap:12px;margin-top:9px;flex-wrap:wrap}
.feed-meta-row .btn{margin-left:auto}
.diff-line.muted{opacity:.65}

/* store switch: icons sit inline with the label */
.seg.compact .seg-btn{display:inline-flex;align-items:center;gap:6px}
.seg.compact .seg-btn svg{opacity:.85}
.seg.compact .seg-btn.active svg{opacity:1}

/* ------------------------------------------------ icon centring
   The glyph boxes held unicode characters whose metrics sit high in the line
   box, so grid centring alone left them looking top-aligned. Flex plus
   line-height:1 centres the glyph itself rather than its line box. */
.gl{
  width:22px;height:22px;flex-shrink:0;
  display:inline-flex;align-items:center;justify-content:center;
  font-size:12px;line-height:1;font-weight:600;text-align:center;
}
.gl svg{display:block}
.ent-icon{display:flex;align-items:center;justify-content:center}
.ent-icon svg{display:block}
.nav-item .ic{display:inline-flex;align-items:center;justify-content:center;width:16px}
.nav-item .ic svg{display:block}
.f-icon,.finding .gl{align-self:flex-start}

/* competitor logos */
.comp-ico{width:34px;height:34px;border-radius:8px;flex-shrink:0;
  border:1px solid var(--img-line);object-fit:cover;background:var(--bg-2)}

/* An icon ahead of a panel title, for cards whose content is a chart. */
.panel-head .ph-ico{display:flex;align-items:center;color:var(--tx-2)}

/* A rating star is always amber, never the text colour, so a rating reads as a
   rating at a glance. */
.star{color:var(--star)}

/* Storefront flags. Sized slightly down so they sit on the text baseline rather
   than pushing line height around, and given a fallback family because a few
   platforms ship no flag glyphs and would otherwise show tofu. */
/* Works for both the inline SVG mark and an optional raster logo. */
.btn svg{flex-shrink:0}

img.store-mark{width:16px;height:16px;border-radius:3.6px;object-fit:contain;
  display:inline-block;vertical-align:-3px}
.seg-btn img.store-mark{width:15px;height:15px}

.flag{font-size:.92em;line-height:1;font-family:"Apple Color Emoji","Segoe UI Emoji",
  "Noto Color Emoji",sans-serif;font-variant-emoji:emoji}

/* ------------------------------------------------ account screen */
.use-row{display:flex;align-items:center;gap:10px;padding:3px 0 7px}
.use-row .k{font-size:14px;color:var(--tx-2)}
.use-row .v{margin-left:auto;font-size:14px}
.bar.good{background:var(--green)}
.bar.mid{background:var(--orange)}
.bar.bad{background:var(--red)}
/* .btn.danger is already defined near the button rules; only the border is new,
   so the delete action reads as destructive before it is hovered. */
.btn.danger{border-color:var(--red)}
.btn[disabled]{opacity:.5;cursor:not-allowed}
/* A toast carrying an action needs room and must not vanish mid-reach. */
.toast.wide{display:flex;align-items:center;gap:12px;max-width:min(560px,92vw);
  text-align:left;line-height:1.45}

/* ------------------------------------------------ reviews analyzer */
.hist-row{display:flex;align-items:center;gap:9px;padding:3px 0;cursor:pointer}
.hist-row:hover .hb{outline:1px solid var(--line-2,var(--line))}
.hist-row .hs{width:26px;font-size:12.5px;color:var(--tx-2);font-variant-numeric:tabular-nums}
.hist-row .hb{flex:1;height:9px;background:var(--bg);border-radius:3px;overflow:hidden}
.hist-row .hf{display:block;height:100%;border-radius:3px}
.hist-row .hf.bad{background:var(--red)}
.hist-row .hf.mid{background:var(--orange)}
.hist-row .hf.good{background:var(--green)}
.hist-row .hn{width:44px;text-align:right;font-size:12.5px;color:var(--tx-2)}

.th-row{padding:11px 14px;border-bottom:1px solid var(--line)}
.th-row:last-child{border-bottom:0}
.th-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.th-c{margin-left:auto;display:flex;gap:4px;flex-wrap:wrap}
.th-q{margin-top:5px;font-size:13.5px;line-height:1.5;color:var(--tx-2);
  border-left:2px solid var(--line);padding-left:9px}

.rv{padding:11px 14px;border-bottom:1px solid var(--line)}
.rv:last-child{border-bottom:0}
.rv-h{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.rv-stars{font-size:13px;letter-spacing:1px;font-family:var(--mono);color:var(--star)}
.rv-stars.bad,.rv-stars.mid,.rv-stars.good{color:var(--star)}
.rv-b{margin-top:4px;font-size:13.5px;line-height:1.55;color:var(--tx-2);
  white-space:pre-wrap;word-break:break-word}

/* ------------------------------------------------ paid search */
.ps-why td{border-bottom:1px solid var(--line);padding:0 14px 9px;font-size:13px;line-height:1.5}
.ps-row td{border-bottom:0;padding-bottom:4px}
tbody tr.ps-why:hover{background:transparent}
.num.pos{color:var(--green)}
.num.neg{color:var(--red)}

/* ------------------------------------------------ rank chart empty state */
.rc-ghost{position:relative;border:1px solid var(--line);border-radius:6px;
  background:var(--panel-alt);overflow:hidden}
.rc-ghost .rc-lab{z-index:1}
.rc-ghost-svg{display:block;width:100%;height:auto;opacity:.6}
/* A 1:1 viewBox means these are already the right pixel size; width:100%
   only matters if the panel resized after render, and uniform scaling
   then keeps the geometry correct rather than shearing it. */
.rc-ghost-ax{opacity:.45}
.rc-ghost-line{fill:none;stroke:var(--blue);stroke-width:2;stroke-dasharray:5 5;opacity:.55}
.rc-ghost-dot{fill:var(--panel);stroke:var(--blue);stroke-width:1.6;opacity:.5}
/* A contained card rather than a wash across the whole panel, so the skeleton
   chart stays legible as a chart around it. */
.rc-ghost-msg{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;
  padding:18px;pointer-events:none}
.rc-ghost-card{background:var(--panel);border:1px solid var(--line);border-radius:8px;
  padding:16px 22px;text-align:center;max-width:440px;pointer-events:auto;
  box-shadow:0 8px 26px rgba(0,0,0,.28)}
.rc-ghost-t{font-size:17px;font-weight:600;margin-bottom:5px}
.rc-ghost-s{font-size:14px;color:var(--tx-2);line-height:1.55;margin-bottom:12px}

/* ------------------------------------------------ rank position chart */
.rc-wrap{position:relative}
/* Axis labels, positioned over the stretched plot as HTML so the type keeps its
   real proportions at any container width. */
.rc-lab{position:absolute;font-family:var(--mono);font-size:11px;color:var(--tx-3);
  pointer-events:none;white-space:nowrap}
.rc-lab-y{left:0;text-align:right;transform:translateY(-50%);padding-right:8px}
.rc-lab-x{bottom:6px;transform:translateX(-50%)}
.rc-ghost-lab{opacity:.6}
.rc-wrap svg{display:block;width:100%;height:auto}
.rc-grid{stroke:var(--line);stroke-width:1}
.rc-ax{fill:var(--tx-3);font-family:var(--mono);font-size:11px}
.rc-cross{stroke:var(--tx-3);stroke-width:1;stroke-dasharray:3 3;pointer-events:none}
#rc-hit{cursor:crosshair}
.rc-tip{position:absolute;top:8px;pointer-events:none;z-index:5;
  background:var(--panel);border:1px solid var(--line-strong);border-radius:var(--r);
  box-shadow:var(--pop);padding:9px 11px;min-width:190px}
.rc-tip-date{font-family:var(--mono);font-size:12px;color:var(--tx-3);
  margin-bottom:7px;padding-bottom:6px;border-bottom:1px solid var(--line)}
.rc-tip-row{display:flex;align-items:center;gap:7px;padding:2px 0;font-size:14px}
.rc-tip-term{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rc-tip-row b{font-family:var(--mono)}
.rc-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0}
.rc-legend{display:flex;flex-wrap:wrap;gap:7px;margin-top:14px;
  padding-top:13px;border-top:1px solid var(--line)}
.rc-leg{display:inline-flex;align-items:center;gap:7px;font:inherit;font-size:14px;
  cursor:pointer;background:var(--panel-alt);border:1px solid var(--line);
  border-radius:99px;padding:4px 11px;color:var(--tx)}
.rc-leg:hover{border-color:var(--line-strong)}
.rc-leg.off{opacity:.42}
.rc-leg.off .rc-dot{background:var(--tx-3) !important}

/* real store marks keep their own colours, so no currentColor inheritance */
.store-mark{flex-shrink:0;display:block}
.seg-btn .store-mark{opacity:1}
.tag .store-mark{vertical-align:-3px;display:inline-block}
.nav-item .ic .store-mark,.side-entity .store-mark{display:block}

/* ------------------------------------------------ localized pricing */

/* Two ratios stacked on a shared axis: what you do above what the market does.
   Stacked rather than side by side because the comparison is between the two
   lengths, and two bars sharing a left edge make that a single glance. */
.rbar{display:inline-block;width:74px;vertical-align:-4px;margin-right:7px}
.rb-row{display:block;height:5px;border-radius:3px;background:var(--panel-alt);
  border:1px solid var(--line);overflow:hidden}
.rb-row + .rb-row{margin-top:3px}
.rb-fill{display:block;height:100%;border-radius:2px}
.rb-fill.you{background:var(--blue)}
.rb-fill.mkt{background:var(--tx-3)}

tr.dim td{opacity:.6}
.tag.tiny{font-size:12px;padding:0 5px;vertical-align:1px}

.pr-find{padding:13px 0;border-bottom:1px solid var(--line)}
.pr-find:last-child{border-bottom:0;padding-bottom:2px}
.pr-find:first-child{padding-top:2px}
.pr-find-head{display:flex;align-items:center;gap:9px;margin-bottom:5px}
.pr-find-head b{font-size:15px}
.pr-find p{margin:0 0 5px;font-size:14px;line-height:1.55;color:var(--tx-2)}

/* Competitor prices as a row of chips in ascending order, so the shape of the
   local market is legible before any individual number is read. */
.pr-peers{display:flex;flex-wrap:wrap;gap:6px;padding:2px 0}
.pr-peer{display:inline-flex;flex-direction:column;gap:1px;padding:4px 9px;
  border:1px solid var(--line);border-radius:var(--r-sm);background:var(--panel-alt);
  max-width:180px}
.pr-peer i{font-style:normal;font-size:12px;color:var(--tx-3);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pr-peer b{font-family:var(--mono);font-size:13px}
.pr-peer.under{border-color:var(--line-strong)}
.pr-peer.you{background:var(--blue-tint);border-color:var(--blue-line)}
.pr-peer.you i,.pr-peer.you b{color:var(--blue)}

@media (max-width:720px){
  .pr-peer{max-width:132px}
  .rbar{width:52px}
}

/* ------------------------------------------------ google sign-in */
/* Google's brand guidelines want their mark on a neutral surface with the label
   beside it, not recoloured to match ours, so this button opts out of the
   gradient the other buttons use. */
.google-btn{justify-content:center;gap:10px;background:var(--panel);
  border-color:var(--line-strong);font-size:16px;padding:7px 11px}
.google-btn:hover{background:var(--panel-alt)}
.google-btn svg{flex-shrink:0}

/* A handed-out sample app, marked so nobody mistakes it for one they added and
   wonders why it does not count against their plan. */
.starter-tag{font-size:12px;color:var(--tx-3);border:1px solid var(--line);
  border-radius:99px;padding:0 7px;margin-left:6px;vertical-align:1px;white-space:nowrap}

/* ------------------------------------------------ keyword suggestion chips */
.kw-suggest{margin-top:13px;padding-top:12px;border-top:1px solid var(--line)}
.kw-chips{display:flex;flex-wrap:wrap;gap:6px}
.kw-chips .btn{padding:3px 9px}
.kw-quick.done{color:var(--green);border-color:var(--green-line);
  background:var(--green-tint);cursor:default;opacity:1}
.kw-quick.done:hover{background:var(--green-tint);border-color:var(--green-line)}
.kw-quick svg{flex-shrink:0}

/* A long identifier stacks instead of being clipped. An Android package name
   runs to forty characters, which a right-aligned flex cell simply cut off. */
.kv.kv-id{flex-direction:column;align-items:flex-start;gap:2px}
.kv.kv-id .v{text-align:left;font-size:14px;overflow-wrap:anywhere;
  word-break:break-all;max-width:100%;user-select:all}
.kv .v{min-width:0;overflow-wrap:anywhere}
.kv .k{flex-shrink:0}

/* Storefront picker for localized pricing. */
.cc-pick{white-space:nowrap}
.cc-pick.done{background:var(--blue-tint);border-color:var(--blue-line);color:var(--blue)}
.cc-pick.done:hover{background:var(--blue-tint);border-color:var(--blue-line)}

/* ------------------------------------------------ the magic tool */
/* The one place in the product with colour for its own sake. Justified because
   this panel is a different kind of thing from the others: it recommends rather
   than reports, and the visual break is doing that work. */
.magic-head{display:flex;align-items:center;gap:14px;margin-bottom:16px;
  padding:16px 18px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--panel);position:relative;overflow:hidden}
.magic-head:before{
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.09;
  background:radial-gradient(520px 130px at 8% 50%,#4C90F0,transparent 70%),
             radial-gradient(420px 130px at 42% 50%,#C58AF0,transparent 70%),
             radial-gradient(420px 130px at 78% 50%,#FBB360,transparent 70%);
}
.magic-ic{width:36px;height:36px;border-radius:9px;flex-shrink:0;
  display:grid;place-items:center;background:var(--panel-alt);
  border:1px solid var(--line);position:relative}
.magic-head .ent-title{font-size:19px;font-weight:600}
.magic-head .ent-type{font-size:14.5px;line-height:1.55;color:var(--tx-2);margin-top:2px}

.mg-op{display:flex;gap:13px;padding:14px 0;border-bottom:1px solid var(--line)}
.mg-op:last-child{border-bottom:0;padding-bottom:2px}
.mg-op:first-child{padding-top:2px}
.mg-n{flex:0 0 24px;height:24px;border-radius:50%;display:grid;place-items:center;
  font-size:13px;font-weight:600;background:var(--blue-tint);color:var(--blue);
  border:1px solid var(--blue-line)}
.mg-body{min-width:0;flex:1}
.mg-body b{font-size:15.5px;display:block;margin-bottom:4px}
.mg-body p{font-size:14.5px;line-height:1.6;color:var(--tx-2);margin:0 0 7px}
.mg-foot{display:flex;flex-wrap:wrap;gap:7px;align-items:center}

.mg-ev{padding:12px 0;border-bottom:1px solid var(--line)}
.mg-ev:last-child{border-bottom:0;padding-bottom:2px}
.mg-ev:first-child{padding-top:2px}
.mg-ev-head{display:flex;flex-wrap:wrap;align-items:center;gap:9px;margin-bottom:4px}
.mg-ev-head b{font-size:15px}
.mg-ev p{font-size:14.5px;line-height:1.6;color:var(--tx-2);margin:0}

/* ------------------------------------------------ strategy primer */
.primer{margin-bottom:14px}
.primer.shut .primer-body{display:none}
.primer-body{display:grid;grid-template-columns:1.35fr 1fr;gap:26px}
.primer-steps{display:flex;flex-direction:column;gap:14px}
.pz{display:flex;gap:11px}
.pz-n{flex:0 0 22px;height:22px;border-radius:50%;display:grid;place-items:center;
  font-size:12px;font-weight:600;background:var(--panel-alt);color:var(--tx-2);
  border:1px solid var(--line)}
.pz b{font-size:14.5px;display:block;margin-bottom:3px}
.pz p{font-size:14px;line-height:1.6;color:var(--tx-2);margin:0}
.primer-scores{border-left:1px solid var(--line);padding-left:24px}
.pz-s{padding:7px 0;border-bottom:1px solid var(--line)}
.pz-s:last-child{border-bottom:0}
.pz-s b{font-size:14px;display:block;margin-bottom:2px}
.pz-s span{font-size:13.5px;line-height:1.55;color:var(--tx-2)}
.tag.reach{cursor:help;max-width:190px;white-space:normal;line-height:1.35;
  display:inline-block;text-align:left}
@media (max-width:860px){
  .primer-body{grid-template-columns:1fr;gap:20px}
  .primer-scores{border-left:0;border-top:1px solid var(--line);padding:18px 0 0}
}

/* ------------------------------------------------ listing inspector */
/* The listing's own text, marked up in place. Monospace because the point is
   the characters: a 30-character budget is easier to feel when every glyph is
   the same width. */
.ins-text{font-family:var(--mono);font-size:15px;line-height:1.75;
  background:var(--panel-alt);border:1px solid var(--line);border-radius:var(--r);
  padding:11px 13px;overflow-wrap:anywhere;white-space:pre-wrap}
.ins-text mark{border-radius:2px;padding:1px 2px;cursor:help;
  background:transparent;color:inherit;border-bottom:2px solid}
.mk-duplicate{border-color:var(--red);background:var(--red-tint) !important;color:var(--red) !important}
.mk-ignored{border-color:var(--orange);background:var(--orange-tint) !important;color:var(--orange) !important}
.mk-unindexed{border-color:var(--orange)}

.ins-items{margin-top:12px;border-top:1px solid var(--line);padding-top:4px}
.ins-item{display:flex;gap:10px;align-items:flex-start;padding:10px 0;
  border-bottom:1px solid var(--line)}
.ins-item:last-child{border-bottom:0}
.ins-item > div{flex:1;min-width:0}
.ins-item b{font-size:15px}
.ins-item p{font-size:14px;line-height:1.55;color:var(--tx-2);margin:3px 0 0}
.ins-gain{display:inline-block;margin-left:8px;font-size:13px;font-weight:600;
  color:var(--green);background:var(--green-tint);border:1px solid var(--green-line);
  border-radius:99px;padding:1px 9px}
@media (max-width:720px){
  .ins-item{flex-wrap:wrap}
  .ins-gain{margin-left:0;margin-top:4px}
}

/* ---------------------------------------------------------------- chart tools
   The row above the rank chart: storefront, then the window. Deliberately quiet
   — it is a filter, not a headline, and the chart under it is what matters. */
.rc-tools{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:12px}
.rc-tool-sel{height:30px;padding:0 26px 0 9px;font-size:13px;border-radius:var(--r-sm);
  border:1px solid var(--line-strong);background:var(--btn-bg);color:var(--tx);width:auto}
.rc-tool-static{font-size:13px;color:var(--tx-2);display:inline-flex;align-items:center;gap:6px}
/* `.seg` carries a bottom margin for its usual full-width use above a panel;
   inside this inline row that margin would push the chart down. */
.rc-tools .seg{margin-bottom:0;width:auto}
.rc-tools .seg-btn{flex:0 0 auto;padding:0 12px;height:30px;font-size:13px}
.rc-tools .seg-btn[disabled]{opacity:.4;cursor:not-allowed}
.rc-span{margin-left:auto}

/* A keyword added since the panel loaded. Held briefly so the row that just
   appeared is findable in a long table, then it settles into the rest. */
.kw-fresh{animation:kwIn .9s ease}
@keyframes kwIn{
  0%   {background:var(--blue-tint)}
  70%  {background:var(--blue-tint)}
  100% {background:transparent}
}
@media (prefers-reduced-motion:reduce){.kw-fresh{animation:none}}
