*,*::before,*::after{box-sizing:border-box;}
html,body{height:100%;margin:0;overflow:hidden;background:#fff;
  font-family:'JetBrains Mono',monospace;}

/* Spec: cell=82pt, gap=21pt, margin=50pt → ratios cell:gap=3.905, margin:gap=2.381
   Scale so grid+margins fit inside available viewport (width and height).
   total_w = 13*cell + 12*gap + 2*margin = gap*(13*3.905+12+2*2.381) = gap*67.525
   total_h = 8*cell + 7*gap = gap*(8*3.905+7) = gap*38.238
   With ~70px header: available_h = 100vh - 70px
   gap = min( 100vw/67.525 , (100vh - 70px)/38.238 ) */
:root{
  --hd-h: 96px;
  /* Divisor 43 = 38.238 (grid) + 2×2.381 (top+bottom margin) — 38.238 alone
     made the grid taller than the available space, clipping the top row. */
  --gap: min(calc(100vw / 67.525), calc((100vh - var(--hd-h)) / 43));
  --cell: calc(var(--gap) * 3.905);
  --margin: calc(var(--gap) * 2.381);
}

.page{height:100%;display:flex;flex-direction:column;}

.hd{flex-shrink:0;text-align:center;padding:.9rem 1rem .6rem;}
.hd h1{font-family:'JetBrains Mono',monospace;font-size:clamp(1.1rem,2.2vw,1.6rem);
  font-weight:700;margin:0;letter-spacing:-.01em;}
.hd p{font-size:.78rem;color:#888;margin:.35rem auto 0;max-width:52rem;}
.toggles-row{
  display:flex;align-items:center;justify-content:center;gap:1.4rem;
  margin-top:1.4rem;flex-wrap:wrap;
}
.toggle-group{display:flex;align-items:center;gap:.5rem;}
.toggle-label{font-family:'JetBrains Mono',monospace;font-size:.66rem;font-weight:600;
  letter-spacing:.06em;text-transform:uppercase;color:#999;}
.view-toggle{display:flex;align-items:center;gap:.4rem;}
.vt-btn{
  border:none;background:none;padding:0;font-family:'JetBrains Mono',monospace;
  font-size:.82rem;font-weight:400;color:#aaa;cursor:pointer;transition:color .12s;
}
.vt-btn+.vt-btn::before{content:'/';margin-right:.4rem;color:#ccc;font-weight:400;}
.vt-btn:hover{color:#666;}
.vt-btn.active{color:#111;font-weight:700;}
.poem-jump{
  width:3.2rem;border:none;border-bottom:1px solid #ddd;background:none;
  font-family:'JetBrains Mono',monospace;font-size:.82rem;color:#111;
  text-align:center;padding:.1rem .2rem;outline:none;-moz-appearance:textfield;
}
.poem-jump::-webkit-inner-spin-button,.poem-jump::-webkit-outer-spin-button{-webkit-appearance:none;}
.poem-jump::placeholder{color:#ccc;}
.poem-jump:focus{border-bottom-color:#999;}
.help-btn{
  position:absolute;top:.8rem;right:1rem;width:1.6rem;height:1.6rem;border-radius:50%;
  border:1px solid #ddd;background:#fff;color:#888;font-size:.8rem;font-weight:700;
  cursor:pointer;display:flex;align-items:center;justify-content:center;
  text-decoration:none;transition:background .12s,color .12s;
}
.help-btn:hover{background:#f5f4f0;color:#444;}
.hd{position:relative;}

.gw{
  flex:1;min-height:0;
  display:flex;align-items:center;justify-content:center;
  padding-bottom:var(--margin);
  position:relative;
  overflow:hidden;
}

.grid-nav{
  display:grid;
  grid-template-columns:1fr auto;
  grid-template-rows:auto 1fr;
  gap:.5rem .6rem;
}
.col-rail{
  grid-column:1;grid-row:1;
  display:flex;gap:var(--gap);align-items:center;justify-content:center;
}
.row-rail{
  display:flex;flex-direction:column;gap:var(--gap);align-items:center;justify-content:center;
}
.row-rail-r{grid-column:2;grid-row:2;}
.nav-btn{
  border:none;background:none;padding:0;
  font-family:'JetBrains Mono',monospace;font-size:.66rem;font-weight:500;
  color:#111;cursor:pointer;transition:opacity .15s,color .12s;
  display:flex;align-items:center;justify-content:center;
  opacity:0;pointer-events:none;
}
.col-rail .nav-btn{width:var(--cell);}
.row-rail .nav-btn{height:var(--cell);width:3ch;}
.grid-nav:has(.pc.zoomed) .nav-btn.active{opacity:1;pointer-events:auto;}

.grid-clip{grid-column:1;grid-row:2;overflow:hidden;position:relative;}

.grid{
  transition:transform .18s ease-out;
  display:grid;
  grid-template-columns:repeat(13,var(--cell));
  grid-template-rows:repeat(8,var(--cell));
  gap:var(--gap);
  grid-auto-flow:dense;
}

.legend{
  position:absolute;left:0;bottom:0;
  width:calc(var(--cell)*2 + var(--gap));height:calc(var(--cell)*2 + var(--gap));
  padding:1.15rem 1.25rem;font-size:.6rem;line-height:1.5;
  font-family:'JetBrains Mono',monospace;font-weight:300;
  display:flex;flex-direction:column;justify-content:center;
  background:#fff;pointer-events:none;
}
.legend strong{display:block;text-align:center;font-size:.58rem;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:#111;margin-bottom:.4rem;}
.legend-row{display:flex;align-items:center;gap:.35rem;color:#444;font-weight:300;white-space:nowrap;}
.legend-swatch{width:8px;height:8px;border-radius:1px;flex-shrink:0;}
.legend.structure-only .legend-device{display:none;}

.pc{
  width:100%;height:100%;
  cursor:pointer;display:flex;align-items:center;justify-content:center;
  border-radius:4px;user-select:none;position:relative;
  transition:transform .09s ease-out, filter .3s ease, opacity .3s ease;
  will-change:transform;
}
.pc:focus-visible{outline:2px solid #1D7058;outline-offset:1px;}
.grid.zoom-active .pc:not(.zoomed){filter:grayscale(1) brightness(1.05);opacity:.55;}
.glyph-wrap{width:100%;height:100%;display:flex;align-items:center;justify-content:center;transition:opacity .18s ease;}
.glyph-wrap svg{width:100%;height:100%;display:block;}

/* ── Zoom ── */
.pc.zoomed{
  z-index:5;
  background:#fff;
  border-radius:6px;
}
.zc-hover-lbl{
  width:100%;height:100%;display:flex;align-items:center;justify-content:center;
  text-align:center;font-family:'JetBrains Mono',monospace;font-weight:700;
  font-size:7.5px;color:#333;padding:2px;pointer-events:none;
  overflow:hidden;word-break:break-word;
}
.zc-card{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  display:flex;flex-direction:column;
  background:#fff;border-radius:6px;overflow:hidden;
}
.zc-body{
  flex:1;min-height:0;display:flex;align-items:flex-start;justify-content:center;
  overflow:hidden;padding:8px;
}
.zc-bars{width:100%;height:100%;}

.zc-book{display:flex;align-items:flex-start;gap:10px;height:100%;}
.zc-book-jp{display:flex;align-items:flex-start;gap:4px;flex-shrink:0;height:100%;}
.zc-book-num{
  writing-mode:vertical-rl;text-orientation:mixed;
  font-family:'Iansui','Hiragino Mincho ProN','Yu Mincho',serif;font-size:5px;color:#999;
  letter-spacing:.15em;flex-shrink:0;align-self:stretch;
  display:flex;align-items:center;justify-content:center;
}
.zc-book-divider{width:1px;background:#e4e1db;align-self:stretch;flex-shrink:0;}
.zc-book-en{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px;}
.zc-book-title{
  font-family:'JetBrains Mono',monospace;font-weight:700;
  font-size:7px;color:#111;text-align:center;margin-bottom:2px;
}
.zc-book-block{display:flex;flex-direction:column;gap:1px;}
.zc-book-lbl{font-family:'JetBrains Mono',monospace;font-weight:700;color:#888;}
.zc-book-lines{font-family:'Ibarra Real Nova',Georgia,serif;color:#333;line-height:1.4;word-break:break-word;}
.zc-book-line{
  display:block;width:fit-content;max-width:100%;
  border-bottom:0.22em solid transparent;padding-bottom:0.12em;margin-bottom:0.12em;
}

.gz-sidebar{
  height:100%;flex-shrink:0;
  display:flex;flex-direction:column;border-radius:2px;overflow:hidden;
}
.gz-sb-seg{flex-shrink:0;}
.gz-text{
  writing-mode:vertical-rl;text-orientation:mixed;
  font-family:'Iansui','Hiragino Mincho ProN','Yu Mincho',serif;
  width:1.1em;flex-shrink:0;
  height:100%;overflow:hidden;
  line-height:1.35;letter-spacing:.04em;color:#1a1a1a;
}
.gz-ch{padding:0 .5px;border-radius:1px;background-clip:padding-box;border:1px solid transparent;box-sizing:border-box;}

/* ── By-Author layout ── */
.author-grids{
  display:flex;flex-direction:column;
  width:100%;height:100%;
}
.author-panels-row{
  flex:1;min-height:0;
  overflow-x:auto;overflow-y:hidden;
  display:flex;flex-wrap:nowrap;gap:1.5rem;align-items:stretch;justify-content:center;
  padding:.75rem 1.5rem;
}
.author-panel{
  display:flex;flex-direction:column;align-items:center;gap:.6rem;
  flex:0 0 clamp(180px,17vw,280px);
}
.author-panel-label{
  font-family:'JetBrains Mono',monospace;font-weight:700;font-size:.85rem;color:#333;
  text-align:center;white-space:nowrap;flex-shrink:0;
}
.author-mini-grid{
  flex:1;min-height:0;
  display:grid;
  grid-template-columns:repeat(10,1fr);
  grid-template-rows:repeat(10,1fr);
  grid-auto-flow:column;
  direction:rtl;
  gap:4px;width:100%;
}
.author-cell{direction:ltr;}
.author-cell{
  cursor:pointer;overflow:hidden;
  transition:transform .1s ease;
}
.author-cell:hover{transform:scale(1.35);z-index:5;position:relative;box-shadow:0 2px 8px rgba(0,0,0,.25);}
.author-cell.author-hl{box-shadow:0 0 0 2px #fff;position:relative;z-index:3;}
.author-grids[data-hl] .author-cell:not(.author-hl){opacity:.2;transition:opacity .08s;}
.author-cell svg{width:100%;height:100%;display:block;}
.author-legend{
  flex-shrink:0;
  display:flex;flex-direction:row;align-items:center;justify-content:center;
  flex-wrap:wrap;gap:.15rem 1rem;
  padding:.35rem 1rem;
  border-top:1px solid #eee;
  font-size:.6rem;line-height:1.5;
  font-family:'JetBrains Mono',monospace;font-weight:300;
}
.author-legend strong{font-size:.58rem;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:#111;}
.author-legend .legend-row{display:flex;align-items:center;gap:.35rem;color:#444;font-weight:300;white-space:nowrap;}
.author-legend .legend-swatch{width:8px;height:8px;border-radius:1px;flex-shrink:0;}
.author-legend.structure-only .legend-device{display:none;}
/* ── Total view ─────────────────────────────────────────────────── */
.total-grids{
  display:flex;flex-direction:column;
  width:100%;height:100%;
}
.total-panels-row{
  flex:1;min-height:0;
  overflow-x:auto;overflow-y:hidden;
  display:flex;flex-wrap:nowrap;gap:2rem;align-items:stretch;justify-content:center;
  padding:.75rem 2rem;
}
.total-panel{
  display:flex;flex-direction:column;align-items:center;gap:.6rem;
  min-width:30px;
}
.total-bar-wrap{
  flex:1;min-height:0;width:100%;
  border-radius:3px;overflow:hidden;
}
.total-bar-wrap svg{display:block;width:100%;height:100%;}
.total-seg{cursor:pointer;transition:opacity .08s;}
.total-panel-count{
  flex-shrink:0;
  font-family:'JetBrains Mono',monospace;font-size:.58rem;font-weight:300;
  color:#888;text-align:center;padding-top:.25rem;
}
.total-grids[data-hl] .total-seg:not(.total-hl){opacity:.2;}
/* Lock legend height so bar charts don't shift when hover text appears */
#totalLegend{flex-wrap:nowrap;overflow:hidden;}
#totalSegInfo{min-height:1.5em;line-height:1.5;}

.author-poem-info{
  font-family:'JetBrains Mono',monospace;font-weight:700;font-size:.72rem;
  color:#111;letter-spacing:.01em;
  margin-right:.5rem;padding-right:.75rem;border-right:1px solid #ddd;
  min-width:8rem;white-space:nowrap;
}

/* ── Modal overlay ── */
.overlay{
  display:none;position:fixed;inset:0;z-index:200;
  background:#ffffff;
  overflow:hidden;
}
.overlay.open{display:flex;flex-direction:column;}

.modal-bar{
  flex-shrink:0;display:flex;align-items:center;justify-content:space-between;
  padding:.9rem 1.25rem;
  background:#fff;
}
.modal-title{
  text-align:center;flex:1;min-width:0;padding:0 1rem;
}
.modal-title-main{
  font-family:'JetBrains Mono',monospace;font-size:clamp(1.1rem,2.2vw,1.6rem);
  font-weight:bold;color:#111;line-height:1.2;
}
.modal-title-sub{
  font-size:.78rem;color:#888;margin-top:.15rem;
}
.modal-bar-right{display:flex;align-items:center;gap:1rem;}
.mnav-arrow{
  border:none;background:none;padding:.2rem;cursor:pointer;
  font-size:1.2rem;line-height:1;color:#444;transition:color .1s;
}
.mnav-arrow:hover{color:#111;}
.mnav-arrow:disabled{opacity:.3;cursor:default;}
.mnav-arrow:disabled:hover{color:#444;}
.mbtn-close{
  border:none;background:none;padding:.2rem;cursor:pointer;
  font-size:1rem;color:#888;transition:color .1s;
}
.mbtn-close:hover{color:#111;}

.modal-body{flex:1;min-height:0;display:grid;grid-template-columns:1fr 1fr;}

.jp-panel{
  position:relative;
  display:flex;align-items:stretch;justify-content:center;
  background:#ffffff;border-right:1px solid #e4e1db;overflow:hidden;
  padding:1.2rem 1rem;
}
/* justify-content:center but NOT align-items:center — centering the cross axis
   on the flex container clips overflow from both ends, making the top
   unreachable. margin:auto on .jp-inner centers it when it fits and falls
   back to top-anchored scrolling when it doesn't. */
.jp-scroll{
  flex:1;min-width:0;display:flex;justify-content:center;
  overflow-y:auto;overflow-x:hidden;
}
.jp-inner{
  display:flex;flex-direction:row;align-items:stretch;gap:.6rem;
  margin:auto 0;
}
.jp-sidebar{
  width:8px;flex-shrink:0;display:flex;flex-direction:column;
  border-radius:4px;overflow:hidden;align-self:stretch;
}
.jp-sidebar-seg{flex-shrink:0;}
.jp-chars-area{
  display:flex;align-items:center;justify-content:center;
  padding:.4rem 0;
}
.jp-chars{
  writing-mode:vertical-rl;text-orientation:mixed;
  font-family:'Iansui','Hiragino Mincho ProN','Yu Mincho','MS Mincho',serif;
  font-size:clamp(1rem,2.6vh,1.7rem);
  letter-spacing:.06em;color:#1a1a1a;
  /* height:max-content prevents the browser from resolving the cross-size
     against an implicit ancestor figure and wrapping into a second column. */
  height:max-content;
}
.jp-ch{
  display:inline-block;
  padding:.16em .09em;
  border:2px solid transparent;box-sizing:border-box;
}
/* position:relative (not flex) — flex would size the group to kanji+furigana
   side by side, shifting each kanji's position in the column depending on
   whether the adjacent word is annotated. */
.jp-ruby-group{position:relative;display:inline-block;}
/* Furigana reads to the RIGHT in vertical text (toward the prior column),
   absolutely positioned so it never affects the kanji's layout. */
.jp-furigana{
  position:absolute;top:50%;left:100%;
  transform:translateY(-50%);
  margin-left:.08em;
  font-family:'Iansui','Hiragino Mincho ProN','Yu Mincho',serif;
  font-size:.42em;color:#999;
  white-space:nowrap;
}

.title-jp{
  writing-mode:vertical-rl;text-orientation:mixed;
  font-family:'Iansui','Hiragino Mincho ProN','Yu Mincho',serif;
  font-size:clamp(.65rem,1.1vw,.9rem);
  letter-spacing:.1em;color:#888;
  white-space:nowrap;
  position:absolute;top:1rem;right:3rem;
}
.jp-legend{
  flex-shrink:0;
  display:flex;flex-direction:column;align-items:center;
  gap:.25rem;
  padding:.6rem 1.5rem 1.2rem;
  border-top:1px solid #eee;
  font-size:.78rem;line-height:1.5;
  font-family:'JetBrains Mono',monospace;font-weight:300;color:#444;
}
.jp-legend .lgd-items{
  display:flex;flex-direction:row;flex-wrap:wrap;
  justify-content:center;gap:.15rem 1.2rem;
}
.jp-legend .lgd-title{
  display:block;text-align:center;font-size:.58rem;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;color:#111;margin-bottom:.4rem;
}
.jp-legend .lrow{display:flex;align-items:center;gap:.35rem;line-height:1.3;font-weight:300;}
.jp-legend .lsw{width:11px;height:11px;border-radius:2px;flex-shrink:0;}

.en-panel{
  padding:1.5rem 2rem 1.5rem 3.5rem;overflow-y:auto;background:#fff;
}
.trans-grid{
  display:flex;flex-direction:column;gap:1.5rem;
}
.trans-block{min-width:0;}
.trans-label{
  font-family:'JetBrains Mono',monospace;font-size:.72rem;font-weight:700;
  letter-spacing:.03em;color:#888;margin-bottom:.4rem;
}
.trans-lines{display:flex;flex-direction:column;}
.tl-row{}
.tl{
  display:inline-block;width:fit-content;max-width:100%;
  font-family:'Ibarra Real Nova',Georgia,serif;font-size:.92rem;line-height:1.65;
  color:#222;
  border-bottom:3px solid transparent;padding-bottom:.15rem;margin-bottom:.3rem;
}
.no-data{color:#bbb;font-style:italic;font-size:.8rem;}
.dw-en{
  background-clip:padding-box;border-radius:2px;padding:0 .08em;
  -webkit-box-decoration-break:clone;box-decoration-break:clone;
}

/* ── Tied-highlight glow ── */
/* .jp-ch is one span per CHARACTER — a per-character box-shadow draws
   separate halos around every glyph of a multi-char word. A permanent
   transparent border (reserved space) turns visible only at left/right
   always, top/bottom only at .run-start/.run-end, tracing one outline
   around the whole word without shifting layout. */
.jp-ch.glow{
  border-left-color:rgba(255,255,255,.9);
  border-right-color:rgba(255,255,255,.9);
  filter:brightness(1.12) saturate(1.25);
  transition:border-color .12s,filter .12s;
  position:relative;z-index:1;
}
.jp-ch.glow.run-start{border-top-color:rgba(255,255,255,.9);}
.jp-ch.glow.run-end{border-bottom-color:rgba(255,255,255,.9);}
.dw-en.glow{
  box-shadow:0 0 0 2px rgba(255,255,255,.9), 0 0 10px 3px rgba(0,0,0,.35);
  filter:brightness(1.12) saturate(1.25);
  transition:box-shadow .12s,filter .12s;
  position:relative;z-index:1;
}
.gz-ch.glow{
  border-left-color:rgba(255,255,255,.9);
  border-right-color:rgba(255,255,255,.9);
  filter:brightness(1.12) saturate(1.25);
  transition:border-color .12s,filter .12s;
  position:relative;z-index:1;
}
.gz-ch.glow.run-start{border-top-color:rgba(255,255,255,.9);}
.gz-ch.glow.run-end{border-bottom-color:rgba(255,255,255,.9);}

.hover-tip{
  display:none;position:fixed;z-index:300;pointer-events:none;
  background:rgba(20,20,20,.94);color:#fff;
  border-radius:4px;padding:.35rem .6rem;
  font-family:'JetBrains Mono',monospace;font-size:.72rem;font-weight:500;
  white-space:normal;max-width:22rem;
  box-shadow:0 2px 10px rgba(0,0,0,.25);
}
.hover-tip.show{display:block;}
.hover-tip.flip{}

/* ── First-visit walkthrough ── */
.intro-overlay{
  display:none;position:fixed;inset:0;z-index:400;
  background:rgba(20,18,15,.55);
  align-items:center;justify-content:center;
}
.intro-overlay.open{display:flex;}
.intro-card{
  position:relative;background:#fff;border-radius:10px;
  width:min(30rem,84vw);height:auto;max-height:90vh;
  display:flex;flex-direction:column;
  padding:1.4rem 1.8rem 1.2rem;
  box-shadow:0 10px 40px rgba(0,0,0,.25);
  overflow:hidden;
}
.intro-header{
  display:flex;align-items:flex-start;justify-content:space-between;
  gap:.75rem;margin-bottom:.55rem;flex-shrink:0;
}
.intro-title{
  font-family:'JetBrains Mono',monospace;font-size:1rem;font-weight:700;
  color:#111;margin:0;flex:1;
}
.intro-steps{display:block;overflow-y:auto;min-height:0;flex:1;}
.intro-step{display:none;}
.intro-step.active{display:block;}
.intro-step p{font-size:.84rem;line-height:1.55;color:#444;margin:0 0 .65rem;text-align:left;}
.intro-step strong{color:#222;}
.intro-swatches{display:flex;flex-direction:column;gap:.4rem;margin:.2rem 0 .55rem;}
.intro-swatch-row{font-size:.82rem;color:#444;line-height:1.55;margin-bottom:.3rem;}
.intro-dots{display:flex;gap:.4rem;margin:0;flex-shrink:0;}
.intro-footer{
  display:flex;align-items:center;justify-content:space-between;
  flex-shrink:0;padding-top:.7rem;margin-top:.5rem;
}
.intro-dot{width:6px;height:6px;border-radius:50%;background:#ddd;transition:background .2s;}
.intro-dot.active{background:var(--dc,#2E9E6B);}
.mbtn{padding:.3rem .75rem;border-radius:4px;border:none;
  background:#fff;cursor:pointer;font-size:.8rem;font-weight:500;color:#444;
  transition:background .1s;}
.mbtn:hover{background:#f0efe9;}
.mbtn:disabled{opacity:.4;cursor:default;}
.intro-nav-btn{
  border:none;background:none;padding:0;
  font-family:'JetBrains Mono',monospace;
  font-size:.82rem;font-weight:400;color:#aaa;
  cursor:pointer;transition:color .12s;
}
.intro-nav-btn:hover{color:#666;}
.intro-nav-btn:disabled,.intro-nav-btn:disabled:hover{opacity:.35;color:#aaa;cursor:default;}
.intro-nav-btn.primary{color:#111;font-weight:700;}
.intro-nav-btn.primary:hover{color:#555;}

/* ── Intro step 2: poem glance grid ── */
.intro-poem-grid-2x2{
  display:grid;
  grid-template-rows:repeat(2,66px);
  grid-auto-columns:66px;
  grid-auto-flow:column;
  gap:5px;width:fit-content;margin:.4rem auto;
}
.intro-mgc{
  display:block;width:66px;height:66px;
  border-radius:4px;cursor:default;
  padding:2px;transition:background .12s;
  position:relative;direction:ltr;overflow:hidden;
}
.intro-mgc:hover{background:#fff;}
.intro-step .view-toggle{justify-content:center;margin:.3rem 0 0;}

/* ── Intro step 1: side-by-side poem translations ── */
.intro-poem-pair{display:flex;gap:.8rem;margin:.4rem 0 .1rem;}
.intro-poem-block{
  flex:1;border-left:2px solid #e8e8e8;
  padding:.35rem 0 .35rem .7rem;
  font-family:'Ibarra Real Nova',Georgia,serif;font-size:.84rem;line-height:1.65;color:#222;
}
.intro-poem-lbl{
  font-family:'JetBrains Mono',monospace;font-size:.65rem;font-weight:700;
  letter-spacing:.03em;color:#888;margin-bottom:.4rem;
}
.intro-poem-grid-4{display:grid;grid-template-columns:1fr 1fr;gap:.55rem;}
.intro-poem-caption{
  font-family:'JetBrains Mono',monospace;font-size:.62rem;color:#aaa;
  text-align:center;margin-top:.45rem;
}

/* ── Intro step 3: zoom demo ── */
.intro-zoom-demo{
  display:flex;justify-content:center;align-items:center;padding:.6rem 0 .3rem;
}
.intro-zoom-cell{
  display:block;width:68px;height:68px;overflow:hidden;
  border-radius:4px;transition:width .35s,height .35s;cursor:default;
}
.intro-zoom-cell.zoomed{width:168px;height:168px;}
.intro-zoom-btns{display:flex;gap:2rem;justify-content:center;margin-top:.4rem;}
.mbtn:disabled:hover{background:#fff;}
.intro-close{
  border:none;background:none;
  font-size:1.1rem;color:#999;cursor:pointer;line-height:1;padding:.3rem;flex-shrink:0;
}
.intro-close:hover{color:#444;}

/* ── Mobile ─────────────────────────────────────────────────────────
   Narrow viewports: flip grid to 8 cols × 13 rows, recalculate --gap
   for the new grid dimensions, compact the header, stack modal panels.
   ------------------------------------------------------------------ */
@media (max-width:640px){
  :root{
    --hd-h: 64px;
    /* 10×10 grid — subtract 48px legend bar from height budget:
       total_w = 10*cell + 9*gap + 2*margin = gap*(10×3.905 + 9 + 2×2.381) = gap×52.812
       total_h = 10*cell + 9*gap + margin   = gap*(10×3.905 + 9 + 2.381)   = gap×50.431 */
    --gap: min(calc(100vw / 52.81), calc((100dvh - var(--hd-h) - 48px) / 50.43));
  }

  /* iOS: svh = small (stable) viewport — doesn't resize when address bar shows/hides,
     preventing 1fr row jitter on vertical swipes. */
  .page{ height:100svh; }

  /* No zoom on mobile — kill the 100 GPU compositor layers and the
     zoom-only transitions that would otherwise fire on every tap. */
  .pc{ will-change:auto; transition:none; }

  /* Compact header */
  .hd{ padding:.4rem 2.8rem .35rem 1rem; }
  .hd h1{ font-size:clamp(.85rem,4vw,1rem); }
  .hd p{ display:none; }
  .toggles-row{ margin-top:.4rem; gap:.25rem .75rem; }
  .toggle-label{ display:none; }

  /* Grid: columns sized by --cell (width-constrained), rows fill available height */
  .gw{ align-items:stretch; }
  .grid-nav{ height:100%; }
  .grid{
    grid-template-columns:repeat(10,var(--cell));
    grid-template-rows:repeat(10,1fr);
    height:100%;
  }

  /* Legend: pull out of grid-clip, render as a bottom bar below the grid.
     grid-clip loses position:relative so the absolute legend re-parents to .gw. */
  .grid-clip{ position:static; overflow:visible; }
  .gw{ padding-bottom:48px; }
  .legend{
    position:absolute; left:0; right:0; bottom:0;
    width:auto; height:auto;
    flex-direction:row; flex-wrap:wrap;
    align-items:center; justify-content:flex-start;
    gap:.2rem .65rem;
    padding:.35rem .75rem;
    border-top:1px solid #e8e6e0;
    font-size:.54rem;
  }
  .legend strong{ display:inline; margin-right:.4rem; }

  /* Modal — jp gets fixed slice, en fills the rest and scrolls internally.
     svh = small (stable) viewport — prevents layout shift when address bar
     appears/disappears during ← → modal navigation. */
  .modal-body{
    grid-template-columns:1fr;
    grid-template-rows:38svh 1fr;
    overflow:hidden;
  }
  .jp-panel{
    border-right:none;
    border-bottom:1px solid #e4e1db;
    min-height:0;
  }
  .en-panel{
    padding:1rem 1.25rem 1.5rem;
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
    min-height:0;
  }
  .modal-bar{ padding:.45rem .75rem; }
  .modal-title-main{ font-size:clamp(.85rem,4vw,1rem); }
  .modal-title-sub{ font-size:.7rem; }
  /* Larger touch targets for prev/next/close */
  .mnav-arrow{ font-size:1.4rem; padding:.3rem .65rem; min-width:44px; min-height:44px; }
  .mbtn-close{ padding:.3rem .5rem; min-width:44px; min-height:44px; }

  /* Author view: stack panels vertically */
  .author-grids{ flex-direction:column; align-items:center; overflow-y:auto; }
  .author-panels-row{
    flex-direction:column; align-items:center;
    overflow-x:hidden; overflow-y:visible;
    flex-wrap:nowrap; justify-content:flex-start;
    height:auto; padding:.5rem .75rem; gap:1rem;
  }
  .author-panel{ flex:0 0 auto; width:min(18rem,92vw); max-width:min(18rem,92vw); }
  .author-mini-grid{ flex:none; width:100%; aspect-ratio:1; }

  /* Total view: prevent label overlap */
  .total-panels-row{ gap:.5rem; padding:.4rem .5rem; }
  .total-panels-row .author-panel-label{
    font-size:.5rem; white-space:normal; overflow:hidden;
    max-height:2.6em; line-height:1.3;
  }
  /* Let the total-view legend wrap so "Kigo" isn't clipped */
  #totalLegend{ flex-wrap:wrap; overflow:visible; }

  /* Fix poem-top clipping in modal (iOS flex overflow + margin:auto = negative margins).
     Spacers center short poems and collapse to 0 when the poem overflows, so the
     top always anchors at y=0 of jp-scroll instead of being pushed above it. */
  .jp-panel{ overflow:hidden; }
  .jp-scroll{
    flex-direction:column;
    align-items:center;
    justify-content:flex-start;
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
  }
  .jp-scroll::before,.jp-scroll::after{ content:''; flex:1; min-height:0; display:block; }
  .jp-inner{ margin:0; flex-shrink:0; }
}
