/* components — topbar controls, rail, settings sheet, cards, states */

/* ---------- icon button: the only chrome control in the topbar ---------- */
.icon-btn{
  flex:none; display:grid; place-items:center;
  width:40px; height:40px; padding:0;
  background:transparent; border:none; border-radius:var(--radius-input);
  color:var(--color-ink-2); cursor:pointer;
  transition:background var(--dur-fast) var(--ease-out),
             color var(--dur-fast) var(--ease-out);
}
.icon-btn:hover{background:var(--color-paper-3); color:var(--color-ink);}
.icon-btn:active{transform:translateY(1px);}
.icon-btn[aria-expanded="true"]{background:var(--color-accent-soft); color:var(--color-accent);}

/* ---------- search: N13 inline pill, flexes to fill the bar ---------- */
.search{position:relative; flex:1; min-width:0; display:flex; align-items:center;}
.search .ic{
  /* top+translateY, not bare `left`: the icon's parent span is an empty, zero-
     height flex item, so without this the absolute box falls back to its static
     position and the icon's TOP edge lands on the vertical centre — about 8px
     low. The magnifier's ink is symmetric in its 24px viewBox (circle y 3-19,
     handle y 17-21, ±0.9 stroke), so true centring is also optically correct. */
  position:absolute; left:11px; top:50%; transform:translateY(-50%);
  color:var(--color-ink-3); pointer-events:none;
  width:1.05rem; height:1.05rem;
}
.search input{
  width:100%; height:38px; padding:0 var(--space-2xs) 0 2.35rem;
  font-family:inherit; font-size:var(--text-md); color:var(--color-ink);
  background:var(--color-paper-2); border:var(--rule-hair) solid var(--color-rule);
  border-radius:var(--radius-pill); outline:none;
  /* box-shadow excluded on purpose — it is the focus ring; see .input. */
  transition:border-color var(--dur-fast) var(--ease-out);
}
.search input::placeholder{color:var(--color-ink-3);}
.search input:hover{border-color:var(--color-rule-2);}
.search input:focus-visible{
  outline:none; border-color:var(--color-accent);
  box-shadow:0 0 0 3px var(--color-accent-soft);
}
.search input::-webkit-search-cancel-button{-webkit-appearance:none; appearance:none;}
.search-clear{
  position:absolute; right:4px; width:30px; height:30px;
  display:none; place-items:center; padding:0;
  background:transparent; border:none; border-radius:var(--radius-pill);
  color:var(--color-ink-3); cursor:pointer;
}
.search-clear:hover{background:var(--color-paper-3); color:var(--color-ink);}
.search.has-value .search-clear{display:grid;}

/* ---------- rail: brand, view switcher, topic index ---------- */
.rail-head{
  display:flex; align-items:flex-start; gap:var(--space-2xs);
  padding:calc(var(--space-sm) + env(safe-area-inset-top)) var(--space-sm) var(--space-xs);
  border-bottom:var(--rule-hair) solid var(--color-rule);
}
.wordmark{
  flex:1; min-width:0; font-family:var(--font-display);
  font-size:var(--text-xl); font-weight:600; letter-spacing:-.01em; line-height:1.2;
}
.wordmark span{
  display:block; font-family:var(--font-body); font-size:var(--text-2xs);
  font-weight:400; letter-spacing:.10em; text-transform:uppercase;
  color:var(--color-ink-3); margin-top:2px;
}
.rail-close{flex:none; width:34px; height:34px;}

/* view switcher — mirrors the mobile tabbar, PC-only affordance */
.rail-views{display:none; flex-direction:column; padding:var(--space-2xs) var(--space-2xs) 0;}
@media (min-width:1024px){.rail-views{display:flex;}}
.rail-view{
  display:flex; align-items:center; gap:var(--space-2xs);
  padding:var(--space-2xs) var(--space-2xs); border:none; background:transparent;
  border-radius:var(--radius-chip); color:var(--color-ink-2);
  font-size:var(--text-md); text-align:left; cursor:pointer;
  transition:background var(--dur-fast) var(--ease-out),
             color var(--dur-fast) var(--ease-out);
}
.rail-view:hover{background:var(--color-paper-3); color:var(--color-ink);}
.rail-view[aria-current="true"]{color:var(--color-accent); background:var(--color-accent-soft);}
.rail-view .count{
  margin-left:auto; font-family:var(--font-mono); font-size:var(--text-2xs);
  font-variant-numeric:tabular-nums; color:var(--color-ink-3);
}
.rail-view[aria-current="true"] .count{color:var(--color-accent);}
.rail-view .count:empty{display:none;}

/* topic index — group label + flat link list, hairline separated */
.rail-group{
  padding:var(--space-sm) var(--space-sm) var(--space-3xs);
  font-family:var(--font-mono); font-size:var(--text-2xs);
  letter-spacing:.10em; text-transform:uppercase; color:var(--color-ink-3);
}
.rail-link{
  display:flex; align-items:baseline; gap:var(--space-2xs);
  padding:var(--space-2xs) var(--space-sm);
  color:var(--color-ink-2); text-decoration:none; font-size:var(--text-md);
  border-left:var(--rule-thick) solid transparent;
  transition:background var(--dur-fast) var(--ease-out),
             color var(--dur-fast) var(--ease-out);
}
.rail-link:hover{background:var(--color-paper-3); color:var(--color-ink);}
.rail-link[aria-current="page"]{
  color:var(--color-accent); border-left-color:var(--color-accent);
  background:var(--color-accent-soft); font-weight:500;
}
.rail-link .n{
  flex:none; font-family:var(--font-mono); font-size:var(--text-2xs);
  font-variant-numeric:tabular-nums; color:var(--color-ink-3);
}
.rail-link[aria-current="page"] .n{color:var(--color-accent);}

/* ---------- bottom tabbar ---------- */
.tab{
  flex:1; min-width:0; position:relative;
  display:flex; flex-direction:column; align-items:center; gap:3px;
  padding:var(--space-2xs) 2px calc(var(--space-2xs) - 1px);
  border:none; background:transparent; color:var(--color-ink-3);
  font-size:var(--text-2xs); cursor:pointer;
  transition:color var(--dur-fast) var(--ease-out);
}
.tab:hover{color:var(--color-ink-2);}
.tab[aria-current="true"]{color:var(--color-accent);}
.tab-badge{
  position:absolute; top:2px; left:calc(50% + .55rem);
  min-width:1.15em; padding:0 .3em; border-radius:var(--radius-pill);
  background:var(--color-accent); color:var(--color-accent-ink);
  font-family:var(--font-mono); font-size:var(--text-2xs); font-weight:600;
  font-variant-numeric:tabular-nums; line-height:1.45;
}
.tab-badge:empty{display:none;}

/* ---------- settings sheet ---------- */
.sheet-head{
  display:flex; align-items:center; gap:var(--space-2xs);
  padding:calc(var(--space-sm) + env(safe-area-inset-top)) var(--space-sm) var(--space-xs);
  border-bottom:var(--rule-hair) solid var(--color-rule);
}
.sheet-head h2{
  flex:1; font-family:var(--font-display); font-size:var(--text-lg); font-weight:600;
}
.field{padding:var(--space-sm) 0; border-bottom:var(--rule-hair) solid var(--color-rule);}
.field:last-child{border-bottom:none;}
.field-label{
  display:flex; align-items:center; gap:var(--space-3xs); margin-bottom:var(--space-2xs);
  font-family:var(--font-mono); font-size:var(--text-2xs);
  letter-spacing:.09em; text-transform:uppercase; color:var(--color-ink-3);
}
.field-note{margin-top:var(--space-2xs); font-size:var(--text-xs); color:var(--color-ink-3);}

/* segmented control — one shape for font size / theme / accent */
.segment{
  display:flex; gap:2px; padding:2px;
  background:var(--color-paper-3); border-radius:var(--radius-input);
}
.segment button{
  flex:1; min-width:0; display:flex; align-items:center; justify-content:center;
  gap:var(--space-3xs); padding:var(--space-2xs) var(--space-3xs);
  border:none; background:transparent; border-radius:7px;
  color:var(--color-ink-2); font-size:var(--text-sm); white-space:nowrap;
  cursor:pointer; transition:background var(--dur-fast) var(--ease-out),
                             color var(--dur-fast) var(--ease-out);
}
.segment button:hover{color:var(--color-ink);}
.segment button[aria-checked="true"]{
  background:var(--color-paper-2); color:var(--color-accent); font-weight:500;
  box-shadow:0 1px 2px oklch(0% 0 0 / .06);
}
/* font-size segment previews its own step — the control demonstrates itself */
.segment .fs1{font-size:var(--text-xs);}  .segment .fs2{font-size:var(--text-sm);}
.segment .fs3{font-size:var(--text-md);}  .segment .fs4{font-size:var(--text-lg);}

/* switch row — label left, state right; text carries state, not just colour */
.switch{
  width:100%; display:flex; align-items:center; gap:var(--space-2xs);
  padding:var(--space-2xs) var(--space-2xs) var(--space-2xs) var(--space-3xs);
  border:var(--rule-hair) solid var(--color-rule); border-radius:var(--radius-input);
  background:var(--color-paper-2); color:var(--color-ink-2);
  font-size:var(--text-md); text-align:left; cursor:pointer;
  transition:border-color var(--dur-fast) var(--ease-out),
             color var(--dur-fast) var(--ease-out);
}
.switch:hover{border-color:var(--color-rule-2); color:var(--color-ink);}
.switch .ic{margin-left:var(--space-3xs);}
.switch .switch-label{flex:1; min-width:0;}
.switch .switch-state{
  flex:none; font-family:var(--font-mono); font-size:var(--text-2xs);
  letter-spacing:.06em; text-transform:uppercase; color:var(--color-ink-3);
}
.switch[aria-pressed="true"]{
  border-color:var(--color-accent); color:var(--color-accent);
  background:var(--color-accent-soft);
}
.switch[aria-pressed="true"] .switch-state{color:var(--color-accent);}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:var(--space-3xs);
  padding:var(--space-2xs) var(--space-sm); min-height:38px;
  border:var(--rule-hair) solid transparent; border-radius:var(--radius-input);
  background:var(--color-accent); color:var(--color-accent-ink);
  font-size:var(--text-md); font-weight:500; white-space:nowrap; cursor:pointer;
  transition:opacity var(--dur-fast) var(--ease-out),
             background var(--dur-fast) var(--ease-out);
}
.btn:hover{opacity:.9;}
.btn:active{transform:translateY(1px);}
.btn:disabled{opacity:.5; cursor:default; transform:none;}
.btn-ghost{
  background:var(--color-paper-2); color:var(--color-ink-2);
  border-color:var(--color-rule);
}
.btn-ghost:hover{background:var(--color-paper-3); color:var(--color-ink); opacity:1;}
.btn-block{width:100%;}
.btn-danger{color:var(--color-danger);}

/* ---------- inputs ---------- */
.input{
  width:100%; padding:var(--space-2xs) var(--space-xs);
  font-family:inherit; font-size:var(--text-md); color:var(--color-ink);
  background:var(--color-paper-2); border:var(--rule-hair) solid var(--color-rule);
  border-radius:var(--radius-input); outline:none;
  /* box-shadow is deliberately not transitioned: it draws the focus ring, and a
     ring that fades in reads as lag to keyboard users. */
  transition:border-color var(--dur-fast) var(--ease-out);
}
.input::placeholder{color:var(--color-ink-3);}
.input:focus-visible{
  outline:none; border-color:var(--color-accent);
  box-shadow:0 0 0 3px var(--color-accent-soft);
}

/* ---------- context line — the de-emphasised page title ---------- */
.context{
  display:flex; align-items:baseline; flex-wrap:wrap; gap:var(--space-3xs) var(--space-2xs);
  margin-bottom:var(--space-md);
}
.context-crumb{
  font-family:var(--font-mono); font-size:var(--text-2xs);
  letter-spacing:.09em; text-transform:uppercase; color:var(--color-ink-3);
}
.context-title{
  width:100%; font-family:var(--font-display); font-size:var(--text-xl);
  font-weight:600; letter-spacing:-.01em; line-height:1.25;
  overflow-wrap:anywhere; min-width:0;
}

/* ---------- section band — count-led, hairline, no display type ---------- */
.band{
  display:flex; align-items:baseline; gap:var(--space-2xs);
  margin:var(--space-lg) 0 var(--space-sm); padding-bottom:var(--space-3xs);
  border-bottom:var(--rule-hair) solid var(--color-rule-2);
}
.band:first-child{margin-top:0;}
.band-name{
  font-size:var(--text-md); font-weight:600; color:var(--color-ink);
  overflow-wrap:anywhere; min-width:0;
}
.band-count{
  margin-left:auto; flex:none; font-family:var(--font-mono);
  font-size:var(--text-2xs); font-variant-numeric:tabular-nums; color:var(--color-ink-3);
}
/* category label inside a band — quieter still */
.cat{
  margin:var(--space-md) 0 var(--space-2xs);
  font-family:var(--font-mono); font-size:var(--text-2xs);
  letter-spacing:.09em; text-transform:uppercase; color:var(--color-ink-3);
}

/* ---------- card grid — auto-fill, no breakpoint guessing ---------- */
.grid{display:grid; gap:var(--space-sm); grid-template-columns:minmax(0,1fr);}
@media (min-width:640px){
  .grid{grid-template-columns:repeat(auto-fill,minmax(min(100%,20rem),1fr));}
  .grid-wide{grid-template-columns:repeat(auto-fill,minmax(min(100%,26rem),1fr));}
}

/* ---------- card — the focus of the page. Generous, hairline-bordered. --- */
.card{
  display:flex; flex-direction:column; min-width:0;
  padding:var(--space-sm) var(--space-sm) var(--space-2xs);
  background:var(--color-paper-2);
  border:var(--rule-hair) solid var(--color-rule);
  border-radius:var(--radius-card);
}
@media (min-width:640px){
  .card{padding:var(--space-md) var(--space-md) var(--space-2xs);}
}

/* headword — serif, the largest type on the page */
.hw{
  font-family:var(--font-display); font-size:var(--text-2xl); font-weight:600;
  line-height:1.2; letter-spacing:-.015em; color:var(--color-ink);
  overflow-wrap:anywhere; min-width:0;
}
.hw-row{display:flex; align-items:baseline; gap:var(--space-2xs); flex-wrap:wrap;}
.pos{
  flex:none; font-family:var(--font-mono); font-size:var(--text-2xs);
  letter-spacing:.04em; color:var(--color-ink-3); white-space:nowrap;
}
.ipa{
  margin-top:var(--space-3xs); font-family:var(--font-mono); font-size:var(--text-sm);
  color:var(--color-ink-3); overflow-wrap:anywhere;
}
.gloss{
  margin-top:var(--space-2xs); font-size:var(--text-lg); font-weight:500;
  line-height:1.45; color:var(--color-ink);
}

/* example block — separated by a rule, not a coloured side-stripe */
.ex{
  margin-top:var(--space-sm); padding-top:var(--space-xs);
  border-top:var(--rule-hair) solid var(--color-rule);
}
.ex-en{
  font-family:var(--font-display); font-size:var(--text-md);
  line-height:1.6; color:var(--color-ink-2); overflow-wrap:anywhere;
}
.ex-zh{margin-top:var(--space-3xs); font-size:var(--text-sm); line-height:1.55; color:var(--color-ink-3);}

/* sentence card — English leads in serif, no headword row */
.sent-en{
  font-family:var(--font-display); font-size:var(--text-xl); font-weight:500;
  line-height:1.45; color:var(--color-ink); overflow-wrap:anywhere; min-width:0;
}
.sent-zh{margin-top:var(--space-2xs); font-size:var(--text-md); line-height:1.55; color:var(--color-ink-2);}
.scene{
  margin-top:var(--space-2xs); font-family:var(--font-mono); font-size:var(--text-2xs);
  letter-spacing:.06em; color:var(--color-ink-3); overflow-wrap:anywhere;
}

/* card footer — numeral + actions live here, so the headword row stays clean */
.card-foot{
  display:flex; align-items:center; gap:var(--space-3xs);
  margin-top:auto; padding-top:var(--space-2xs);
  /* Actions sit right. justify-content does the pushing rather than a flex:1 on
     the lead span, because most cards now have no lead element at all. */
  justify-content:flex-end;
}
.card-n{
  flex:1; min-width:0; font-family:var(--font-mono); font-size:var(--text-2xs);
  font-variant-numeric:tabular-nums; letter-spacing:.06em; color:var(--color-ink-3);
}
.card-act{
  flex:none; display:grid; place-items:center; width:34px; height:34px; padding:0;
  background:transparent; border:none; border-radius:var(--radius-input);
  color:var(--color-ink-3); cursor:pointer;
  transition:background var(--dur-fast) var(--ease-out),
             color var(--dur-fast) var(--ease-out);
}
/* Touch screens get a 44px box on the controls a reader hits repeatedly. The
   glyph stays the same size — only the hit area grows. Pointer screens keep the
   tighter 34px, which a mouse can hit precisely and which crowds the card less. */
@media (max-width:1023px){
  .card-act{width:44px; height:44px;}
  .icon-btn,.icon-btn.rail-close{width:44px; height:44px;}
  .rail-link{min-height:44px;}
}
.card-act:hover{background:var(--color-paper-3); color:var(--color-accent);}
.card-act:active{transform:translateY(1px);}
.card-act[aria-pressed="true"]{color:var(--color-gold);}
.card-act[aria-pressed="true"] .ic{fill:var(--color-gold);}
.card-act.is-danger:hover{color:var(--color-danger);}
.card-act.is-speaking{color:var(--color-accent);}

/* own-word marker — text label, not a coloured pill */
.mine{
  flex:none; font-family:var(--font-mono); font-size:var(--text-2xs);
  letter-spacing:.08em; text-transform:uppercase; color:var(--color-accent);
}

/* ---------- toast — transient failure notice, sits above the tabbar ---------- */
.toast{
  position:fixed; z-index:60; left:50%; transform:translateX(-50%);
  bottom:calc(var(--tabbar-h) + env(safe-area-inset-bottom) + var(--space-sm));
  max-width:min(92vw,26rem); padding:var(--space-2xs) var(--space-sm);
  background:var(--color-ink); color:var(--color-paper);
  border-radius:var(--radius-pill); font-size:var(--text-sm); text-align:center;
  box-shadow:0 4px 16px oklch(0% 0 0 / .18);
}
.toast[hidden]{display:none;}
@media (min-width:1024px){
  .toast{bottom:var(--space-lg);}
}

/* ---------- self-test veil: blur the Chinese until tapped ---------- */
body.mask-zh .gloss,body.mask-zh .ex-zh,body.mask-zh .sent-zh{
  filter:blur(6px); cursor:pointer; user-select:none;
  transition:filter var(--dur-fast) var(--ease-out);
}
body.mask-zh .gloss.shown,body.mask-zh .ex-zh.shown,body.mask-zh .sent-zh.shown{filter:none;}

/* ---------- custom-word form ---------- */
.form{
  display:flex; flex-direction:column; gap:var(--space-xs);
  padding:var(--space-sm); margin-bottom:var(--space-md);
  background:var(--color-paper-2); border:var(--rule-hair) solid var(--color-rule);
  border-radius:var(--radius-card);
}
.form-row{display:flex; flex-direction:column; gap:var(--space-xs);}
@media (min-width:640px){.form-row{flex-direction:row;} .form-row label{flex:1; min-width:0;}}
.form label{display:flex; flex-direction:column; gap:var(--space-3xs);
  font-size:var(--text-xs); color:var(--color-ink-2);}
.form .req{color:var(--color-accent);}
.form details{
  border:var(--rule-hair) solid var(--color-rule);
  border-radius:var(--radius-input); padding:0 var(--space-xs);
}
.form summary{
  padding:var(--space-2xs) 0; font-size:var(--text-sm);
  color:var(--color-ink-2); cursor:pointer;
}
.form summary:hover{color:var(--color-accent);}
.form details label{margin-bottom:var(--space-xs);}
.form-actions{display:flex; align-items:center; gap:var(--space-2xs); flex-wrap:wrap;}
.form-msg{font-size:var(--text-xs); color:var(--color-danger); min-height:1.2em;}

/* ---------- states: empty · error · account ---------- */
.state{
  display:flex; flex-direction:column; align-items:center; gap:var(--space-2xs);
  padding:var(--space-2xl) var(--space-sm); text-align:center; color:var(--color-ink-3);
}
.state .ic{width:1.75rem; height:1.75rem; stroke-width:1.4; color:var(--color-rule-2);}
.state h3{font-family:var(--font-display); font-size:var(--text-lg);
  font-weight:600; color:var(--color-ink-2);}
.state p{font-size:var(--text-sm); max-width:32ch;}
.state .btn{margin-top:var(--space-2xs);}
.account{display:flex; flex-direction:column; gap:var(--space-2xs);}
.account-who{display:flex; align-items:center; gap:var(--space-3xs);
  font-size:var(--text-md); color:var(--color-ink-2);}
.account-msg{font-size:var(--text-xs); color:var(--color-ink-3); min-height:1.2em;}
.account-msg.is-error{color:var(--color-danger);}
