/* app.css: the 강산 app's shell on paper (SPEC-HARMONY §21.2, §21.4, §21.5).
   Loaded after concepts/names.css and concepts/gangsan.css, before the state stylesheets.
   Tokens, the shared primitives (.primary .btn .textbtn .mk), the header (#top), the toast, the drawer's
   frame, the peek bar and the gate's frame. Paper #F1E6D3, ink #1F2878, mute #5D618C, 1 px ink hairlines.
   Red #E0533A is the memory seal and nothing else (.seal-sq). No dark theme. */

/* ---------- tokens: the names the state stylesheets already use, redefined for paper (§21.5) ---------- */
:root {
  --bg: #F1E6D3;        /* paper (was #050507) */
  --panel: #F1E6D3;     /* the drawer and the gate are paper */
  --fg: #1F2878;        /* ink (was #ECEBE6) */
  --dim: #5D618C;       /* mute: secondary type only (was #6E6E76) */
  --inherit: #5D618C;   /* mute (was #8A9AB8) */
  --faint: #1F2878;     /* ink, used only as a 1 px hairline (was #2A2A30) */
  --scrim: transparent; /* no wash */
  --accent: #E0533A;    /* the seal square, nothing else */
  /* person inks on paper, in palette order (palette.js PAPER_INKS = landscape.js INKS) */
  --p0: #8A6000; --p1: #04756A; --p2: #745D97; --p3: #716923; --p4: #766553; --p5: #346D91; --p6: #91566B; --p7: #477145;
  --safe-t: env(safe-area-inset-top, 0px); --safe-r: env(safe-area-inset-right, 0px);
  --safe-b: env(safe-area-inset-bottom, 0px); --safe-l: env(safe-area-inset-left, 0px);
  --drawer-w: 400px; --gutter: 24px; --app-ease: cubic-bezier(.2, .7, .2, 1);
  --drawer-wide: min(880px, calc(100vw - 2 * var(--inset) - 28px));
  color-scheme: light;
}
@media (max-width: 699px) { :root { --drawer-w: 100vw; --drawer-wide: 100vw; --gutter: 16px; } }

/* ---------- resets for the panels (the drawer, the gate, the lightbox); zero specificity, so state rules win ---------- */
[hidden] { display: none !important; }
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
:where(#drawer, #gate, #lightbox, #peekbar, #toast) :where(h1, h2, h3, h4, p, ul, ol, dl, dd, figure, blockquote) { margin: 0; }
:where(#drawer, #gate, #lightbox) :where(ul, ol) { padding: 0; list-style: none; }
:where(#drawer, #gate, #lightbox) :where(img, svg, canvas, video, audio) { display: block; max-width: 100%; }
:where(#drawer, #gate, #lightbox, #peekbar, #toast, #top) :where(button) {
  background: none; border: 0; padding: 0; margin: 0; cursor: pointer; -webkit-appearance: none; appearance: none;
  text-align: inherit; border-radius: 0; font: inherit; color: inherit; letter-spacing: inherit;
}
:where(#drawer, #gate, #lightbox) :where(button:disabled, button[aria-disabled="true"]) { cursor: default; }
:where(#drawer, #gate, #lightbox) :where(input, select, textarea) { background: transparent; border: 0; border-radius: 0; outline: none; caret-color: var(--fg); font: inherit; color: inherit; letter-spacing: inherit; }
:where(#drawer, #gate, #lightbox) :where(input, textarea)::placeholder { color: var(--dim); opacity: 1; }
:where(#drawer, #gate, #lightbox) a { color: inherit; text-underline-offset: 3px; }
:where(#drawer, #gate) summary { cursor: pointer; }
#drawer, #gate > .g-panel { font: 300 15px/1.5 var(--sans); color: var(--fg); -webkit-font-smoothing: antialiased; }
::selection { background: rgba(31, 40, 120, .16); }
.mono { font-family: var(--mono); font-weight: 300; letter-spacing: .14em; text-transform: uppercase; }

/* ---------- shared primitives ---------- */
/* .primary: the one filled control per panel (kit §4.5): ink fill, paper type, 44 px. */
.primary {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 20px;
  border: 1px solid var(--fg); border-radius: 999px; background: var(--fg); color: var(--bg);
  font: 400 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; white-space: nowrap; cursor: pointer;
}
.primary:hover, .primary:focus-visible { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
.primary:focus-visible { outline: 1px solid var(--fg); outline-offset: 3px; }
.primary:disabled, .primary[aria-disabled="true"] { background: var(--dim); border-color: var(--dim); color: var(--bg); text-decoration: none; }
/* .btn: a hairline control. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 18px;
  border: 1px solid var(--fg); border-radius: 999px; background: transparent; color: var(--fg);
  font: 400 11px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; white-space: nowrap;
}
.btn:hover, .btn:focus-visible { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px; }
.btn:disabled, .btn[aria-disabled="true"] { color: var(--dim); border-color: var(--dim); text-decoration: none; }
/* .textbtn: underlined words. */
.textbtn {
  display: inline-flex; align-items: center; min-height: 32px; color: var(--fg); font: 300 13px var(--sans);
  text-decoration: underline; text-decoration-color: var(--fg); text-decoration-thickness: 1px; text-underline-offset: 4px;
}
.textbtn:hover, .textbtn:focus-visible { text-decoration-thickness: 2px; }
.textbtn:disabled { color: var(--dim); text-decoration-color: var(--dim); }
/* person marks in their paper inks (palette.js also inlines these) */
.mk { display: inline-block; flex: none; width: 8px; height: 8px; border: 1px solid var(--c, var(--fg)); background: var(--c, var(--fg)); vertical-align: baseline; }
.mk.hollow { background: transparent; }
.mk.pc0 { --c: var(--p0); } .mk.pc1 { --c: var(--p1); } .mk.pc2 { --c: var(--p2); } .mk.pc3 { --c: var(--p3); }
.mk.pc4 { --c: var(--p4); } .mk.pc5 { --c: var(--p5); } .mk.pc6 { --c: var(--p6); } .mk.pc7 { --c: var(--p7); }
.ptag { display: inline-flex; align-items: center; white-space: nowrap; }
/* the seal square (E17): the only red, before ink words ("one who was there is living"); filled when no one is */
.seal-sq { display: inline-block; flex: none; box-sizing: border-box; width: 8px; height: 8px; margin-right: 8px; border: 1.5px solid var(--accent); background: transparent; vertical-align: 0; }
.seal-sq.fill { background: var(--accent); }

/* the legend's three sentences: the concept's `.three`, named `.trio` in the app's page (no "three" in index.html) */
#legend .trio { padding-bottom: 12px; margin-bottom: 12px; border-bottom: 1px solid var(--hair); }
#legend .trio p { margin: 0 0 3px; font: 400 13px/1.45 var(--sans); }
#legend .trio p[lang="ko"] { font-family: var(--kr); }

/* ---------- the header (#top, §21.2): in the mount above the frame on wide screens, inside the frame below 980 px ---------- */
#top { align-items: center; gap: 18px; }
#top button {
  position: relative; display: inline-flex; align-items: baseline; padding: 11px 0; margin: -11px 0;
  font: 400 9.5px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; color: var(--ink); white-space: nowrap; cursor: pointer;
}
#top button [lang="ko"] { font-size: 10.5px; letter-spacing: .04em; text-transform: none; }
/* the English half is a flex item, so its leading space (" · family") would be dropped: keep it */
#top button .en { white-space: pre; }
#top button:hover, #top button:focus-visible { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
#drawertoggle .gl { margin-right: 6px; font: 400 12px/1 var(--mono); letter-spacing: 0; }
#drawertoggle .dot { position: absolute; top: 7px; right: -8px; width: 4px; height: 4px; border-radius: 50%; background: var(--ink); }
#add { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
#add .k-ph { display: none; }
#status { color: var(--mute); cursor: default; }
#status .short { display: none; }
#status.act { color: var(--ink); cursor: pointer; }
#status.act .go { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
#status:not(.act):hover { text-decoration: none; }
#solochip { color: var(--ink); }
#solochip .x { margin-left: 8px; font-size: 11px; }
/* below 980 px the header stands inside the frame, where the art (lifted above a phone's card) can reach:
   its words sit on a knock-out of paper, as the captions do, so a crown never runs through them */
@media (max-width: 979px) {
  #top button > span:not(.dot) { background: var(--bg); box-shadow: 0 0 0 3px var(--bg); }
}
@media (max-width: 699px) {
  #top { gap: 14px; }
  #top button { padding: 17px 0; margin: -17px 0; }
  /* §21.7.7: wider targets than the words (≡ alone is 8 px), without moving anything: a hit slop that
     stays inside the gap to the next control; ≡ also reaches toward the screen's edge */
  #top button::before { content: ''; position: absolute; top: 0; bottom: 0; left: -7px; right: -7px; }
  #top #drawertoggle::before { left: -26px; right: -7px; }
  #top #add::before { left: -7px; right: -18px; }
  #help::before { content: ''; position: absolute; inset: -9px; }
  #actions button { position: relative; }
  #actions button::before { content: ''; position: absolute; top: -16px; bottom: -16px; left: -6px; right: -6px; }
  #drawertoggle .k, #drawertoggle .en, #drawertoggle .ls { display: none; }
  #drawertoggle .gl { margin-right: 0; font-size: 14px; }
  #add .k, #add .en, #add .ls { display: none; }
  #add .k-ph { display: inline; }
  #status .full { display: none; }
  #status .short { display: inline; }
  #solochip .en, #solochip .ls { display: none; }
}

/* ---------- the toast: in the concept's #note place (§21.5) ---------- */
#toast {
  position: fixed; z-index: 50; left: 50%; bottom: calc(var(--inset) + 48px); transform: translateX(-50%);
  max-width: min(520px, calc(100vw - 32px)); opacity: 0; pointer-events: none; transition: opacity .2s ease;
}
#toast.on { opacity: 1; }
#toast.on.link { pointer-events: auto; }
#toast .tmsg {
  display: block; width: 100%; padding: 6px 10px; background: var(--bg); border: 1px solid var(--fg);
  font: 400 11px/1.4 var(--mono); letter-spacing: .02em; color: var(--fg); text-align: center; text-transform: none;
}
#toast .tmsg.link { cursor: pointer; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; }
body.sheet #toast { bottom: calc(52vh + 12px); bottom: calc(52dvh + 12px); }
@media (max-width: 699px) { body[data-drawer] #toast { top: calc(var(--safe-t) + 12px); bottom: auto; } }

/* ---------- the drawer: in the card's slot on a desk, the full screen on a phone (§21.5) ----------
   Motion contract with drawer.js: removing [hidden] plays the way in; .closing the way out (drawer.js
   waits 340 ms), then [hidden]. .collapsed = the phone's peek bar. */
#drawer {
  position: fixed; z-index: 20; left: calc(var(--inset) + 14px); top: calc(var(--inset) + 46px); bottom: calc(var(--inset) + 46px);
  width: var(--drawer-w); max-width: calc(100vw - 2 * var(--inset) - 28px);
  display: flex; flex-direction: column; background: var(--bg); border: 1px solid var(--fg);
  animation: wf-drawer-in .24s var(--app-ease) both;
}
#drawer.closing { animation: wf-drawer-out .2s var(--app-ease) both; pointer-events: none; }
#drawer[data-wide="true"] { width: var(--drawer-wide); }
#dhead { flex: none; display: flex; align-items: center; gap: 10px; min-height: 56px; padding: 6px 8px 6px var(--gutter); border-bottom: 1px solid var(--fg); }
#dback { flex: none; max-width: 62%; min-height: 44px; font: 400 10.5px/1 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--fg); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#dback:empty { display: none; }
#dback:hover, #dback:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
#dtabs { flex: none; display: flex; gap: 18px; }
#dtabs:empty { display: none; }
#dtabs button { display: inline-flex; flex-direction: column; align-items: flex-start; justify-content: center; gap: 3px; min-height: 44px; color: var(--dim); box-shadow: inset 0 -1px transparent; }
#dtabs button [lang="ko"] { font: 400 12px/1 var(--kr); letter-spacing: .02em; }
#dtabs button .sep { display: none; }
#dtabs button .en { font: 400 8.5px/1 var(--mono); letter-spacing: .14em; text-transform: uppercase; }
#dtabs button:hover, #dtabs button:focus-visible { color: var(--fg); }
#dtabs button[aria-selected="true"], #dtabs button.on { color: var(--fg); box-shadow: inset 0 -1px var(--fg); }
#dtitle { flex: 1; min-width: 0; text-align: right; font: 400 10px/1.3 var(--mono); letter-spacing: .12em; text-transform: uppercase; color: var(--dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#dfield { flex: none; min-height: 32px; padding: 0 12px; border: 1px solid var(--fg); border-radius: 999px; font: 400 10px/1 var(--mono); letter-spacing: .06em; color: var(--fg); white-space: nowrap; }
#dfield [lang="ko"] { font-size: 11px; letter-spacing: 0; }
#dfield:hover, #dfield:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
#dclose { flex: none; margin-left: auto; width: 44px; height: 44px; display: grid; place-items: center; font: 400 14px/1 var(--mono); color: var(--fg); text-align: center; }
#dclose:hover, #dclose:focus-visible { text-decoration: underline; }
#dbody { flex: 1; min-height: 0; overflow-x: hidden; overflow-y: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; padding: 14px var(--gutter) 40px; scrollbar-width: thin; scrollbar-color: var(--fg) transparent; outline: none; }
#dbody::-webkit-scrollbar { width: 6px; }
#dbody::-webkit-scrollbar-thumb { background: var(--fg); }
#dfoot { flex: none; padding: 14px var(--gutter) calc(14px + var(--safe-b)); border-top: 1px solid var(--fg); background: var(--bg); }
#dfoot:empty { display: none; }
/* 700–979 px: with a card or a drawer the pivot moves right and the readout under the top row's controls;
   the scroll's controls go to the bottom margin there, as they do on the headwaters sheet */
@media (min-width: 700px) and (max-width: 979px) {
  body.carding #actions, body[data-drawer] #actions { top: auto; bottom: calc(var(--inset) / 2 - 6px); right: var(--inset); }
  /* §21.12 (A14): the app's header is wider than the concept's two links, so at these widths the
     scroll's controls always take the bottom margin; the top row is the header's and the readout's */
  #actions { top: auto; bottom: calc(var(--inset) / 2 - 6px); right: var(--inset); }
}
/* the wide TREE sheet reaches past the air's readout (anchored at NOW): the readout is never half under
   it, so it steps away while TREE is open there. In the valley the pivot, and the readout with it, moves
   right of the drawer, so it stays. */
body[data-drawer="tree"] #readout.air { visibility: hidden !important; }
/* the short form's readout stands at the frame's top left: clear of the header's targets in the mount above */
body.short #readout.short { top: calc(var(--inset) + 8px); }
@media (max-width: 699px) {
  /* §21.12 (A14): the header's 44 px targets reach 48 px down the frame, so the readout starts
     under them, in every form; its "또 · also" line wraps inside the screen instead of running off it */
  #readout, #readout.air, body.short #readout.short { top: calc(var(--inset) + 42px); }
  #ro-also { white-space: normal; max-width: calc(100vw - 2 * var(--inset) - 28px); line-height: 1.35; }
  #dfield .le, #dfield .ls { display: none; }
  #dback { flex: 1 1 auto; min-width: 0; max-width: none; }
  #drawer { left: 0; top: 0; bottom: auto; width: 100vw; max-width: none; height: 100vh; height: 100dvh; border: 0; padding: 0 var(--safe-r) 0 var(--safe-l); }
  #dhead { padding-top: calc(var(--safe-t) + 6px); }
}
#peekbar {
  position: fixed; z-index: 20; left: 0; right: 0; bottom: 0; height: calc(64px + var(--safe-b));
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 0 calc(16px + var(--safe-r)) var(--safe-b) calc(16px + var(--safe-l));
  background: var(--bg); border-top: 1px solid var(--fg); font: 300 14px/1.3 var(--sans); color: var(--fg); text-align: left; white-space: nowrap; overflow: hidden;
  animation: wf-peek-in .24s var(--app-ease) both;
}
#peekbar .pk-t { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
#peekbar .pk-up { flex: none; font: 400 14px/1 var(--mono); color: var(--fg); }

/* ---------- the gate (§21.4): a full-window layer with no fill; the panel is paper with an ink hairline ---------- */
#gate {
  position: fixed; z-index: 40; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: calc(var(--safe-t) + 24px) calc(var(--safe-r) + 24px) calc(var(--safe-b) + 24px) calc(var(--safe-l) + 24px);
  background: transparent; overflow-y: auto; overscroll-behavior: contain;
}
#gate > .g-panel { width: 100%; max-width: 440px; margin: auto 0; padding: 32px 30px 28px; border: 1px solid var(--fg); background: var(--bg); }
#gate > *:empty { display: none; }
#gate > .g-quiet { margin: auto 0; padding: 6px 10px; font: 400 11px/1.4 var(--mono); letter-spacing: .02em; color: var(--dim); background: var(--bg); }
#gate > .g-quiet [lang="ko"] { font-size: 12px; letter-spacing: 0; }
@media (max-width: 699px) {
  #gate { padding: calc(var(--safe-t) + var(--inset) + 12px) var(--inset) calc(var(--safe-b) + var(--inset) + 12px); justify-content: flex-start; }
  #gate > .g-panel { max-width: none; padding: 26px 18px 22px; }
}
/* under a gate: the header, the scroll's controls, the legend and the card (the scroll itself stays visible, paused) */
body.gated #top, body.gated #actions, body.gated #views, body.gated #langs, body.gated #viewhint, body.gated #foot, body.gated #help, body.gated #legend, body.gated #card,
body.gated #peekbar, body.gated #tip { visibility: hidden !important; }
/* a blank sheet (no people: an outsider, a join, signed out): the frame and the paper only */
body.blank #actions, body.blank #views, body.blank #langs, body.blank #viewhint, body.blank #foot, body.blank #bands, body.blank #readout, body.blank #fardom { visibility: hidden !important; }

.noscript { position: fixed; inset: 0; display: grid; place-items: center; margin: 0; padding: 24px; background: var(--bg); color: var(--fg); font: 400 13px/1.5 var(--mono); text-align: center; }

/* ---------- motion ---------- */
@keyframes wf-drawer-in { from { opacity: 0; transform: translateX(-10px); } to { opacity: 1; transform: none; } }
@keyframes wf-drawer-out { from { opacity: 1; transform: none; } to { opacity: 0; transform: translateX(-10px); } }
@keyframes wf-peek-in { from { transform: translateY(100%); } to { transform: none; } }
@keyframes wf-fade { from { opacity: 0; } to { opacity: 1; } }
@media (max-width: 699px) {
  @keyframes wf-drawer-in { from { transform: translateY(24px); opacity: 0; } to { transform: none; opacity: 1; } }
}

/* ---------- reduced motion: cut, never glide ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: .001ms !important; animation-delay: 0s !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; transition-delay: 0s !important; scroll-behavior: auto !important; }
}

/* the one-time family-tree tip waits while the drawer is open (it would hang half behind it) */
body:has(#drawer:not([hidden])) #viewhint { display: none; }
