/* UI08 staff console. Daylight work ground for long reading, the member app's dark neutral as the shell,
   one department colour per duty used only as tags and filters. Single family: Noto Sans Thai. */
@font-face{font-family:Tosaa;src:url('/actors-profile-and-industry-pov/fonts/noto-sans-thai-400.woff2') format('woff2');font-weight:400;font-display:swap}
@font-face{font-family:Tosaa;src:url('/actors-profile-and-industry-pov/fonts/noto-sans-thai-500.woff2') format('woff2');font-weight:500;font-display:swap}
@font-face{font-family:Tosaa;src:url('/actors-profile-and-industry-pov/fonts/noto-sans-thai-600.woff2') format('woff2');font-weight:600;font-display:swap}
@font-face{font-family:Tosaa;src:url('/actors-profile-and-industry-pov/fonts/noto-sans-thai-700.woff2') format('woff2');font-weight:700;font-display:swap}
:root{
 --rail:#17191c;--rail-2:#202327;--rail-ink:#ece8e0;--rail-muted:#a9aca5;--rail-line:#ffffff1f;
 --ground:#f4f4f1;--surface:#ffffff;--surface-2:#ecece6;--ink:#1d2124;--muted:#575e5b;--line:#d8d8d0;--line-strong:#b9bab1;/* Fix round 11 Nov 2026 (item 205): the edge of a field to type in or choose from, at least 3:1 on white (3.55) and on the ground (3.22). */--field-line:#878980;
 --primary:#2c3a22;--primary-ink:#f6f7ef;--primary-hover:#3a4b2d;--select:#e7ecd6;--focus:#55702f;
 --now:#9a2a1f;--now-bg:#fbe9e6;--wait:#8a5208;--wait-bg:#fcf0dc;--done:#2f6b3a;--done-bg:#e3f0e4;
 --t-review:#3f4c1f;--t-review-bg:#e5ead1;--t-identity:#2f4566;--t-identity-bg:#dfe6f0;--t-recovery:#45484a;--t-recovery-bg:#e6e6e3;
 --t-finance:#1f5b52;--t-finance-bg:#d8ebe7;--t-content:#3b3566;--t-content-bg:#e5e3ef;--t-events:#5e2f52;--t-events-bg:#efe1ea;
 --t-quests:#6b4718;--t-quests-bg:#f2e6d3;--t-cases:#7a2534;--t-cases-bg:#f3dee1;--t-feedback:#33505b;--t-feedback-bg:#dde6e9;
 --radius:10px;--font:Tosaa,'Noto Sans Thai','Noto Sans SC',system-ui,sans-serif;
 color-scheme:light;
}
*{box-sizing:border-box}
html{background:var(--ground)}
body{margin:0;background:var(--ground);color:var(--ink);font:400 15px/1.7 var(--font);-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
::selection{background:#cfd9ae;color:#141a0e}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:6px}
a{color:inherit;text-underline-offset:3px}
button,input,select,textarea{font:inherit;color:inherit}
h1,h2,h3{margin:0;font-weight:600;line-height:1.45;text-wrap:balance}
.num{font-variant-numeric:tabular-nums}
.sr-only{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
svg.i{width:20px;height:20px;flex:none;fill:none;stroke:currentColor;stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}

/* Shell */
.sc{display:grid;grid-template-columns:256px minmax(0,1fr);min-height:100dvh}
.rail{position:sticky;top:0;height:100dvh;display:flex;flex-direction:column;gap:18px;padding:22px 14px 18px;background:var(--rail);color:var(--rail-ink);overflow:auto;scrollbar-color:#4a4d50 transparent}
.brand{display:flex;align-items:center;gap:10px;padding:0 8px}
.brand .wordmark{width:104px;color:#fff}
.brand span{font-size:12px;color:var(--rail-muted);border-left:1px solid var(--rail-line);padding-left:10px;line-height:1.35}
.who{display:grid;gap:4px;padding:10px 8px 12px;border-bottom:1px solid var(--rail-line)}
.who label{font-size:11px;color:var(--rail-muted)}
.who select{width:100%;min-height:40px;background:var(--rail-2);border:1px solid #7a7d80/* item 205: 3.81:1 on the rail. Was: #ffffff2b (1.70:1) */;border-radius:8px;padding:6px 10px;color:var(--rail-ink)}
.who small{font-size:11px;color:#c9b88f;line-height:1.5}
.nav{display:grid;gap:2px}
.nav h2{font-size:11px;font-weight:500;color:var(--rail-muted);padding:10px 10px 4px}
.nav a{display:flex;align-items:center;gap:10px;min-height:44px;padding:8px 10px;border-radius:8px;text-decoration:none;color:var(--rail-ink);font-size:14px}
.nav a:hover{background:#ffffff0f}
.nav a[aria-current=page]{background:#ffffff17;box-shadow:inset 0 0 0 1px #ffffff1c}
.nav .dot{width:8px;height:8px;border-radius:2px;flex:none}
.nav .count{margin-left:auto;font-size:12px;min-width:24px;text-align:center;padding:1px 7px;border-radius:999px;background:#ffffff14;color:var(--rail-ink)}
.nav .count.hot{background:#f1d9b0;color:#3a2a0c}
.main{min-width:0;display:flex;flex-direction:column}
.top{position:sticky;top:0;z-index:5;display:flex;align-items:center;gap:14px;padding:12px 28px;background:color-mix(in srgb,var(--ground) 92%,transparent);backdrop-filter:saturate(1.2) blur(10px);border-bottom:1px solid var(--line)}
.top .date{font-size:13px;color:var(--muted)}
/* checker finding 23 Oct 2026: the language box keeps the right edge when a page has no work-list search box */.top .lang-wide{margin-left:auto}.search{flex:1;max-width:460px;display:flex;align-items:center;gap:8px;min-height:42px;padding:0 12px;background:var(--surface);border:1px solid var(--field-line)/* item 205. Was: var(--line) */;border-radius:999px}
.search input{flex:1;border:0;background:transparent;min-width:0;outline:0}
.search:focus-within{border-color:var(--focus);box-shadow:0 0 0 3px #55702f26}
/* Fix round 11 Nov 2026 (item 205, owner took the suggestion): every box to type in or choose from has an edge of at least 3:1 (--field-line);
   boxes drawn without an edge (border 0, such as the search word inside .search) keep none. Was: var(--line-strong) 1.96:1 on white,
   var(--line) 1.30:1. */
:is(input:not([type=checkbox],[type=radio],[type=range],[type=file]),select,textarea):not(#field-line){border-color:var(--field-line)}
.top select{min-height:42px;border:1px solid var(--field-line)/* item 205. Was: var(--line) */;border-radius:8px;background:var(--surface);padding:0 10px}
.page{padding:26px 28px 120px;max-width:1240px;width:100%}
.demo-note{font-size:12px;color:var(--muted);margin:0 0 18px}

/* Call sheet ledger */
.sheet-head{display:flex;align-items:end;justify-content:space-between;gap:20px;margin-bottom:18px}
.sheet-head h1{font-size:24px}.sheet-head.duties-head h1{font-size:26px}/* Fix round 11 Nov item 140 (owner answer ข): หน้าที่ may be larger; every other page title is one size (24 px, 20 px on a phone). Was: 26 px for หน้าหลัก, บัญชีของฉัน and ค้นหา too */
.sheet-head p{margin:2px 0 0;color:var(--muted);font-size:14px}
.filters{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 22px}
/* QA B-20 (owner FIX-LIST 31 Oct 2026): ค้นหา shows every sub-part chip with its count (0 too) in an even grid: same width per cell, the
   name on the left and the count on the right, so a row of zeros reads as a tidy table rather than scattered pills. Was: wrapped pills. */
.filters-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(168px,calc(50% - 3px)),1fr));gap:6px}
.filters-grid .chip{justify-content:flex-start;min-width:0;border-radius:10px;padding:4px 10px;text-align:left}
.filters-grid .chip .num{margin-left:auto;padding-left:6px;font-variant-numeric:tabular-nums}
.filters-grid .chip .duty-words{min-width:0;line-height:1.25;text-wrap:balance}/* a long name ("ปัญหาแอปและบัญชี") on a 320 px phone takes two balanced lines inside its cell, never under the count */
.filters-grid .chip .duty-words .tosaa-term{white-space:normal}
.empty.search-none{border-bottom:0;padding:10px 4px}
/* QA B-21: a page the person's duty does not cover: a chevron back at the top, the words in the middle of the screen, no line. */
a.back.refused-back{width:40px;height:40px;min-height:40px;margin:-8px 0 0 -8px;padding:0;justify-content:center;border-radius:10px;color:var(--ink)}
a.back.refused-back svg.i{width:22px;height:22px}
.refused-page{display:grid;place-items:center;min-height:50vh;padding:24px 8px;text-align:center;color:var(--muted);font-size:15px}
.refused-page p{margin:0;text-wrap:balance}
.refused-page strong{color:var(--ink);font-weight:500}
/* QA B-22: password boxes on the invite pages have a show/hide eye inside the box's right end (44 px target). */
.pw-wrap{position:relative;display:block}
.pw-wrap input{padding-right:50px!important}
.pw-eye{position:absolute;top:50%;right:2px;transform:translateY(-50%);display:grid;place-items:center;width:44px;height:44px;border:0;border-radius:8px;background:transparent;color:var(--muted);cursor:pointer}
.pw-eye svg.i{width:20px;height:20px}
.pw-eye.on{color:var(--ink)}
.pw-eye.on::after{content:'';position:absolute;width:22px;height:1.8px;background:currentColor;transform:rotate(-45deg);border-radius:1px}
/* QA B-34 (owner 31 Oct 2026): "ล้างร่าง" and other text buttons are links in every panel (was: the browser's grey box, only styled
   under the old sign-in sample box), and the message check pop-up is one centred card on every screen, with a cross at the top right. */
.linkish{display:inline-flex;align-items:center;min-height:32px;padding:6px 0;border:0;background:none;color:inherit;font:inherit;text-decoration:underline;text-underline-offset:3px;cursor:pointer}
.linkish:hover{color:var(--ink)}
.rep-chip .linkish{justify-content:center;padding:0;text-decoration:none}/* the folder chip's × keeps its look */
.msg-review{width:min(520px,calc(100% - 32px));max-height:calc(100dvh - 48px);padding:22px;border:0;border-radius:18px;background:var(--ground);color:inherit;overflow:auto}
.msg-review::backdrop{background:#000a}
.msg-review h2{margin:0 44px 6px 0;font-size:20px}
.msg-review .consequence{margin:0 0 14px;color:var(--muted);font-size:14px}
.msg-review-x{position:absolute;top:10px;right:10px;display:grid;place-items:center;width:44px;height:44px;border:0;border-radius:10px;background:transparent;color:var(--ink);cursor:pointer}
.msg-review-x:hover{background:var(--surface-2)}
.msg-review-x svg.i{width:22px;height:22px}
.msg-review-body{max-height:40dvh;overflow:auto;padding:14px;border:1px solid var(--line);border-radius:12px;background:var(--surface)}
.msg-review-body .preview-msg{margin:0;padding:0;border:0;background:none;white-space:pre-wrap;overflow-wrap:anywhere;line-height:1.6;font-size:15px}
.msg-review-body .preview-msg+.preview-msg{margin-top:8px}
.msg-review .draft-note{margin:10px 0 16px}
.msg-review-actions{display:grid;gap:10px}
/* Owner 7 Nov 2026 (fix round, Q2-BUG-03): the pop-up before saving a post whose Thai changed under old English or Chinese words (app.js
   askLangs), in the message check's frame: the fields in a box, then the two lines and the two choices. */
.lang-keep h2{text-wrap:balance}.lang-keep p{text-wrap:pretty}
.lang-keep .consequence{margin:0 0 10px}
.lang-keep-list{margin:0 0 10px;padding:10px 14px 10px 34px;border:1px solid var(--line);border-radius:12px;background:var(--surface);font-size:15px;line-height:1.6}
.lang-keep .hint-line{margin:0 0 12px}
/* Owner 7 Nov 2026 (fix round, FX2-08; Q2-B-25): each choice stays on one line down to 320px; on a small phone the two buttons have a
   little less padding, as the sign-out pop-up's do, so the longest label (English "Leave empty and publish") keeps room to spare. */
@media (max-width:400px){.lang-keep .msg-review-actions .btn{padding-inline:12px}}
/* Q2-BUG-15: the result line of เขียนประกาศ's tabs, above the featured box (app.js postsPage). */
.side>.result{margin:0}
/* QA B-44: FAQ question and short answer lines are balanced, so the last line is never one word ("ตัวตน", "ต่อปี"). */
.gov-faq-q .what strong,.gov-faq-q .what small{text-wrap:balance}
.chip{display:inline-flex;align-items:center;gap:6px;min-height:36px;padding:4px 12px;border-radius:999px;border:1px solid var(--line);background:var(--surface);font-size:13px;cursor:pointer}
.chip[aria-pressed=true]{background:var(--ink);border-color:var(--ink);color:#fff}
.band{margin:0 0 30px}
.band-head{display:flex;align-items:baseline;gap:12px;padding:0 0 8px;border-bottom:2px solid var(--ink)}
.band-head h2{font-size:16px}
.band-head .n{font-size:13px;color:var(--muted);white-space:nowrap}/* Owner 7 Nov 2026 (fix round, FX4-39; rule 5 "ข้อความยาว", as the votes page's band count): the count and its word stay on one line ("1 item" read "1" / "item" at 320 px in English). Was: no white-space */
.band-head .hint{margin-left:auto;font-size:12px;color:var(--muted);text-wrap:balance}/* round 2 Q2: the waiting-band hint is two lines on a phone; balanced, so the last line is not a lone "ตัดสิน" */
.rows{list-style:none;margin:0;padding:0}
.row{display:grid;grid-template-columns:76px 132px minmax(0,1fr) auto;/* Owner 26 Oct 2026: no end button. Was: … auto auto */cursor:pointer;align-items:center;gap:14px;min-height:62px;padding:10px 4px;border-bottom:1px solid var(--line);text-decoration:none;color:inherit;position:relative}
.row:hover{background:#ffffff99}
.row .time{font-size:13px;color:var(--muted);line-height:1.3}
.row .time b{display:block;font-weight:600;color:var(--ink);font-size:15px}
.row .what{min-width:0;text-decoration:none;color:inherit;border-radius:6px}
.row .what::after{content:'';position:absolute;inset:0}
.row .tag,.row .state{position:relative}
/* Owner 7 Nov 2026 (fix round, FX4-44): a row's due tag ("ยังไม่กรอกแต้ม") sits under the duty's tag on a computer; on a phone it follows the state in the wrapping tag line. */
.row .tagcell .row-due{display:flex;width:fit-content;margin-top:6px}
.row .time b+*{display:block}
.row.lead{background:#ffffffb8}
.duty-row{grid-template-columns:auto minmax(0,1fr) auto!important;text-decoration:none;color:inherit}
.duty-row .dot{width:10px;height:10px;border-radius:2px}
.check-count{margin:0;font-size:13px;color:var(--muted)}
.upload{display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;margin-top:14px;cursor:pointer}
.upload small{color:var(--muted);font-size:13px}
.upload:focus-within .btn{outline:2px solid var(--focus);outline-offset:2px}
.media-picks button{position:relative}
.media-picks button span{position:absolute;left:6px;bottom:6px;font-size:11px;padding:1px 7px;border-radius:999px;background:#000000a6;color:#fff}
.row .what:hover strong{text-decoration:underline;text-underline-offset:4px}
.row .what strong{display:block;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.row .what small{display:block;font-size:13px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.row:focus-within{background:#fff}
.tag{display:inline-flex;align-items:center;gap:6px;max-width:100%;padding:3px 9px;border-radius:5px;font-size:12px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.tag::before{content:'';width:6px;height:6px;border-radius:1px;background:currentColor;flex:none}
.tone-review{background:var(--t-review-bg);color:var(--t-review)}.tone-identity{background:var(--t-identity-bg);color:var(--t-identity)}.tone-recovery{background:var(--t-recovery-bg);color:var(--t-recovery)}.tone-finance{background:var(--t-finance-bg);color:var(--t-finance)}.tone-content{background:var(--t-content-bg);color:var(--t-content)}.tone-events{background:var(--t-events-bg);color:var(--t-events)}.tone-quests{background:var(--t-quests-bg);color:var(--t-quests)}.tone-cases{background:var(--t-cases-bg);color:var(--t-cases)}.tone-feedback{background:var(--t-feedback-bg);color:var(--t-feedback)}
.dot.tone-review{background:#a8b97a}.dot.tone-identity{background:#8ea6c8}.dot.tone-recovery{background:#a3a6a8}.dot.tone-finance{background:#7fb8ac}.dot.tone-content{background:#a29bd0}.dot.tone-events{background:#c592b6}.dot.tone-quests{background:#d4a868}.dot.tone-cases{background:#d68b98}.dot.tone-feedback{background:#8fb0bc}
.state{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:500;padding:3px 9px;border-radius:999px;white-space:nowrap}
.state.now{background:var(--surface-2);color:var(--ink)}.state.waiting{background:var(--wait-bg);color:var(--wait)}.state.done{background:var(--done-bg);color:var(--done)}
/* Owner 7 Nov 2026 (fix round, Q2-S-05): a sign-up that did not get a seat is red (governance-ui.js SIGNUP_STATE). */.state.stop{background:var(--now-bg);color:var(--now)}
/* Step 7 S1: the reason under a part turned down in the review's "result by part" list, and the works' links. Its pill
   colours by band like every other state pill (follow-up F1). */
.part-reason{display:block;margin-top:4px;font-size:14px;color:var(--muted);overflow-wrap:anywhere}
.files li>span{min-width:0}.work-link{font-size:13px;overflow-wrap:anywhere}
.empty{padding:22px 4px;color:var(--muted);font-size:14px;border-bottom:1px solid var(--line)}
.empty strong{display:block;color:var(--ink);font-weight:500}

/* Work view */
.work{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:28px;align-items:start}/* Owner 23 Oct 2026 night (board screenshot): the side column goes beside the work only when the content area, not the whole screen, has room for both; otherwise under it. Pages with a decision panel (.dock) keep their layout. */.main{container-type:inline-size;container-name:main}@container main (max-width:860px){.work:not(:has(.dock)){grid-template-columns:minmax(0,1fr)}}
/* Fix round 11 Nov item 163: when the console's content area is narrow (the bench at 1366 px gives it about 670 px; a 900-990 px window too),
   a page with a side panel puts the panel under the work, so the work column is not squeezed to 246 px (badges over member codes, "มีค").
   Was: the 340 px panel stayed beside the work at any content width above the phone layout. */
@container main (max-width:720px){.work{grid-template-columns:minmax(0,1fr)}}
.back{display:inline-flex;align-items:center;gap:6px;min-height:44px;margin:-8px 0 8px -6px;padding:0 8px;border-radius:8px;text-decoration:none;color:var(--muted);font-size:14px}
.back:hover{color:var(--ink);background:var(--surface-2)}
.item-head{display:grid;gap:8px;padding-bottom:18px;border-bottom:1px solid var(--line);margin-bottom:22px}
.item-head .meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;font-size:13px;color:var(--muted)}
.item-head h1{font-size:24px}
.sec{margin:0 0 26px}
.sec h2{font-size:15px;margin:0 0 10px;display:flex;align-items:center;gap:8px}
.sec h2 .private{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:500;color:var(--t-identity);background:var(--t-identity-bg);padding:2px 9px 2px 7px;border-radius:999px}
.sec h2 .private svg.i{width:13px;height:13px;stroke-width:2}
/* Owner 7 Nov 2026 (fix round, FX3-09): the label column gives way when the facts are narrow (the left column beside a decision panel in the
   bench's 928 px staff frame was 245 px: a 190 px label left the value 55 px and cut every word); the value keeps at least 150 px or 60%.
   As wide as before from about 340 px. Was: grid-template-columns:minmax(120px,190px) minmax(0,1fr). */
dl.facts{display:grid;grid-template-columns:minmax(min(120px,40%),190px) minmax(min(150px,60%),1fr);margin:0;border-top:1px solid var(--line)}
dl.facts dt,dl.facts dd{margin:0;padding:10px 0;border-bottom:1px solid var(--line)}
dl.facts dt{color:var(--muted);font-size:14px;padding-right:12px}
dl.facts dd{overflow-wrap:anywhere}
/* Owner 7 Nov 2026 (fix round, Q2-BUG-12): the name an application was sent under, below the account's name now. Additive. */
dl.facts dd .name-was{display:block;margin-top:2px;font-size:13px;color:var(--muted)}/* Owner 7 Nov 2026 (fix round, FX3-03): the name row's own name keeps each part whole too. Was: only the old name in .name-was. */dl.facts dd .name-whole{white-space:nowrap}
.prose{white-space:pre-wrap;margin:0;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:14px 16px}
.files{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.files li{display:flex;align-items:center;gap:12px;padding:10px 12px;background:var(--surface);border:1px solid var(--line);border-radius:8px}
.files li small{color:var(--muted);margin-left:auto;font-size:12px}
.files button{min-height:36px}
/* QA B-07 (owner 31 Oct 2026): "เปิดดู" stays on one line and keeps its width; on a narrow screen the note beside a document's name
   ("ไม่มีไฟล์แนบ", a file name) moves under the name, so the name is not squeezed either. Was: the button broke into "เปิด / ดู". */
.files li>.btn,.files .gov-row-actions .btn{white-space:nowrap;flex:none}
@media (max-width:640px){.files li:has(>small){display:grid;grid-template-columns:auto minmax(0,1fr) auto;column-gap:12px;row-gap:2px}
 .files li:has(>small)>svg{grid-row:1/3}.files li:has(>small)>span{grid-column:2}.files li:has(>small)>small{grid-column:2;margin-left:0;overflow-wrap:anywhere}
 .files li:has(>small)>.btn{grid-column:3;grid-row:1/3}}
.spine{position:relative;list-style:none;margin:0;padding:0 0 0 20px;display:grid;gap:14px}
.spine::before{content:'';position:absolute;left:0;top:6px;bottom:6px;width:2px;border-radius:1px;background:var(--line-strong)}
.spine li{position:relative}
.spine li::before{content:'';position:absolute;left:-25px;top:8px;width:12px;height:12px;border-radius:50%;background:var(--ground);border:2px solid var(--line-strong)}
.spine li.staff::before{border-color:var(--primary);background:var(--primary)}
.spine li.member::before{border-color:var(--t-identity)}
.spine li.note::before{border-color:var(--wait);background:var(--wait-bg)}
.spine time{display:block;font-size:12px;color:var(--muted)}
.spine p{margin:2px 0 0;white-space:pre-wrap;overflow-wrap:anywhere}/* Fix round 11 Nov 2026 item 128: a long unbroken word (a file name in a vote cancel reason) wraps. Was: no overflow-wrap, so it pushed the page wider. */
/* Owner 7 Nov 2026 (fix round, S-68): a date in a history line stays on one line ("30 ม.ค. 2027"), as registration/app.css .date-whole. Additive. */
.spine .date-whole{white-space:nowrap}
.spine .who{display:inline;padding:0;border:0;font-size:13px;font-weight:500}

/* Decision dock */
.dock{position:sticky;top:84px;display:grid;gap:16px;background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:18px;box-shadow:0 10px 28px #1d21240f}
.dock h2{font-size:15px}
.dock p.consequence{margin:0;font-size:13px;color:var(--muted);line-height:1.65}
.dock .tabs,.gov-faq-sets,.status-seg{display:flex;gap:4px;padding:3px;background:var(--surface-2);border-radius:9px}
.dock .tabs button,.gov-faq-sets button,.status-seg button{flex:1;min-height:38px;border:0;border-radius:7px;background:transparent;font-size:13px;cursor:pointer}
.dock .tabs button[aria-selected=true],.gov-faq-sets button[aria-selected=true],.status-seg button[aria-pressed=true]{background:var(--surface);box-shadow:0 1px 3px #0000001a;font-weight:500}
/* Fix round 11 Nov item 152: a short button, tab or band title stays on one line on a narrow screen ("关闭", "Open this post", "Do not
   approve", "Ask for changes", "Waiting on someone else", "Save the names", "Import existing members"); a tab that does not fit moves to a
   second row of the tab bar instead. Was: the words broke inside the button ("关" / "闭", "Open" / "this post"). */
.dock .tabs{flex-wrap:wrap}.dock .tabs button{white-space:nowrap;padding-inline:8px}
.head-actions .btn,.fv-top .btn{white-space:nowrap}.fv-top .btn{flex:none}
.band-head{flex-wrap:wrap}.band-head h2{white-space:nowrap}/* the line beside the title goes under it when they do not fit */
.field{display:grid;gap:6px;font-size:14px}
.dock form,.dock .confirm{display:grid;gap:18px}
.dock form .btn{margin-top:4px}
.field textarea,.field input[type=text],.field select{width:100%;min-height:44px;border:1px solid var(--line-strong);border-radius:8px;background:#fff;padding:9px 11px}
.field textarea{min-height:110px;resize:vertical;line-height:1.6}
.checks{display:grid;gap:6px;margin:0;padding:0;border:0}
.checks legend{font-size:14px;margin-bottom:4px}
.checks label{display:flex;align-items:flex-start;gap:10px;min-height:36px;font-size:14px}
/* Owner 7 Nov 2026 (fix round, Q2-B-09): a tick box keeps its size beside a label of two lines (the work-permit check was squeezed to 13 px wide).
   Was: no flex rule, so the box shrank. */
.checks input{width:18px;height:18px;margin-top:4px;accent-color:var(--primary);flex:none}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;min-height:46px;padding:8px 18px;border-radius:9px;border:1px solid var(--line-strong);background:var(--surface);cursor:pointer;font-weight:500;text-decoration:none;color:var(--ink)}
.btn:hover{background:var(--surface-2)}
.btn.primary{background:var(--primary);border-color:var(--primary);color:var(--primary-ink)}
.btn.primary:hover{background:var(--primary-hover)}
.btn.danger{color:var(--now);border-color:#e3b7b0}
.btn:disabled{opacity:.5;cursor:not-allowed}
.btn.full{width:100%}
.result{font-size:13px;padding:10px 12px;border-radius:8px}
.result.ok{background:var(--done-bg);color:var(--done)}
.result.err{background:var(--now-bg);color:var(--now)}
.notice{font-size:14px;line-height:1.65;padding:12px 14px;border-radius:10px;background:var(--surface);border:1px solid var(--line);color:var(--ink)}
.dock .notice{background:var(--surface-2);border:0;font-size:13px}
.notice.warn{background:var(--wait-bg);color:#5d3a07}
.preview-msg{border:1px dashed var(--line-strong);border-radius:10px;padding:12px 14px;background:#fbfbf8;white-space:pre-wrap;font-size:14px}

/* Settings */
.parent{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:14px 16px}
.parent h3{font-size:15px;display:flex;align-items:center;gap:10px}
.parent ul{list-style:none;margin:8px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.parent li{font-size:13px;padding:4px 10px;border-radius:999px;background:var(--surface-2)}
.parent li.added{background:var(--t-quests-bg);color:var(--t-quests);font-weight:500}
.parent .none{font-size:13px;color:var(--muted)}
.frames{display:grid;grid-template-columns:200px minmax(0,1fr);gap:18px;align-items:end}
.frame{position:relative;overflow:hidden;border-radius:16px;background:#111 center/cover no-repeat;border:1px solid var(--line-strong)}
.frame.phone{aspect-ratio:390/844}
.frame.desk{aspect-ratio:16/10}
.frame video,.frame img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.frame .panel{position:absolute;background:#0f1d18b8;backdrop-filter:blur(10px);color:#fff;border-radius:12px;padding:10px;display:grid;gap:6px;font-size:10px}
.frame.phone .panel{left:8%;right:8%;top:30%}
.frame.desk .panel{right:6%;top:18%;width:32%}
.frame .panel i{display:block;height:14px;border-radius:4px;background:#ffffff2e}
.frame .credit{position:absolute;left:8px;bottom:6px;font-size:9px;color:#ffffffc0}
.media-picks{display:flex;flex-wrap:wrap;gap:8px}
.media-picks button{width:96px;aspect-ratio:2/3;border-radius:10px;border:2px solid transparent;background:#222 center/cover;cursor:pointer}
.media-picks button[aria-pressed=true]{border-color:var(--primary);box-shadow:0 0 0 2px #fff inset}

/* Phone layout: list first, item full screen, decisions in a sticky bottom dock. */
.tabbar{display:none}
.m-only{display:none}

/* Association board: post list and composer */
.head-actions{display:flex;flex-wrap:wrap;gap:8px}
/* Owner 26 Oct 2026: a merged duty's create tiles: icon in its colour, a short label on one line, two per row on a phone.
   Was (same day): .head-actions[data-duty-create] .btn{flex:1 1 auto;white-space:nowrap}. */
.create-tiles{display:grid;grid-template-columns:repeat(4,max-content);gap:8px}
.create-tile{display:flex;align-items:center;gap:10px;padding:8px 14px 8px 8px;border:1px solid var(--line);border-radius:14px;background:var(--surface);color:var(--ink);text-decoration:none;white-space:nowrap}
.create-tile>span{display:grid;place-items:center;flex:none;width:34px;height:34px;border-radius:10px}
.create-tile>span svg.i{width:20px;height:20px}
.create-tile strong{font-size:14px;font-weight:500;line-height:1.3}
.create-tile:hover{border-color:var(--line-strong)}
.create-tile:focus-visible{outline-offset:2px}
@media (max-width:900px){.sheet-head:has(.create-tiles){flex-direction:column;align-items:stretch;gap:12px}.create-tiles{grid-template-columns:repeat(2,minmax(0,1fr))}}
.side{display:grid;gap:16px;position:sticky;top:84px}
.side .slots{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:16px 18px;margin:0}
.slots h2{display:flex;justify-content:space-between;align-items:baseline;font-size:16px}
.slots h2 .num{font-size:14px;color:var(--muted);font-weight:500}
.hint-line{margin:4px 0 10px;font-size:13px;color:var(--muted);line-height:1.6}
.slot-list{list-style:none;margin:0;padding:0;counter-reset:slot}
.slot-list li{display:grid;grid-template-columns:22px minmax(0,1fr) auto;gap:10px;align-items:center;padding:8px 0;border-top:1px solid var(--line);counter-increment:slot}
.slot-list li::before{content:counter(slot);font-variant-numeric:tabular-nums;color:var(--muted);font-size:13px}
.slot-list li.this .what strong{color:var(--primary)}
.slot-list .what{display:grid;min-width:0}
/* QA S-57: the title is a button that opens the full title (app.js slotPeek); it looks like the line it was. */
.slot-list button.what{margin:0;padding:4px 0;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer;min-height:44px;align-content:center;border-radius:6px}
.slot-list button.what:hover strong{text-decoration:underline}
.slot-list button.what:focus-visible{outline:2px solid var(--primary);outline-offset:2px}
.slot-peek{width:min(460px,calc(100% - 32px));max-height:calc(100dvh - 48px);overflow:auto;padding:22px;border:0;border-radius:18px;background:var(--ground);color:inherit}
.slot-peek::backdrop{background:#000a}
.slot-peek .eyebrow{margin:0 0 6px;font-size:13px;color:var(--muted)}
.slot-peek h2{margin:0 0 10px;font-size:19px;line-height:1.45;overflow-wrap:break-word;text-wrap:pretty}
.slot-peek-summary{margin:0 0 14px;color:var(--muted);font-size:14px;line-height:1.6}
.slot-peek .notice{margin:0 0 14px}
.slot-peek .hint-line{margin:0 0 14px}
.slot-peek .head-actions{justify-content:flex-end}
.slot-peek .head-actions .btn{flex:1}
.slot-list .what strong{font-weight:500;font-size:14px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.slot-list .what small{font-size:12px;color:var(--muted)}
.slot-list .btn{min-height:36px;padding:4px 12px;font-size:13px}
/* Owner 1 Nov 2026 (S-56): move up / down beside "เอาออก", and the "จบแล้ว" tag of an ended event that keeps its place. */
.slot-list .slot-acts{display:flex;gap:4px;align-items:center}
/* Owner 7 Nov 2026 (fix round, Q2-B-02: smaller, narrower buttons that keep their proportion; "เอาออก" a bin icon): the move buttons and the
   bin are one small square, 32px on a computer (44px on phones and tablets, the touch rule below), so the title has more room. Was: 36px
   move squares (min-width:36px;padding:4px) and "เอาออก" in words, about 76px. */
.slot-list .btn.slot-move,.slot-list .btn.slot-remove{min-width:32px;min-height:32px;padding:0;display:inline-grid;place-items:center}
.slot-list .btn.slot-remove{margin-left:4px}
.slot-list .btn.slot-move:disabled{opacity:.35;cursor:default}
/* Q2-Q10 (owner chose ก): on a phone the move and bin buttons go to a second row under the title, so the title and its date have the whole
   row. Was: one row, the title cut to 62px at 320 and its date under the up button ("9 ต.ค. 202"). */
@media (max-width:640px){.slot-list li{grid-template-columns:22px minmax(0,1fr);row-gap:2px}.slot-list .slot-acts{grid-column:2;justify-content:flex-start}}
.slot-list .slot-day{white-space:nowrap}
.slot-list .slot-ended{display:inline-block;margin-left:6px;padding:0 6px;border-radius:999px;background:var(--surface-2);color:var(--ink);font-size:11px;white-space:nowrap}
/* Fix round 11 Nov 2026 item 150: the date column is as wide as its whole date (a date is drawn on one line since the shared word pass), so it never runs into the title. Was: 92px (72px at 900 px and below), and a whole date overflowed onto the title. */.post-row{grid-template-columns:max-content minmax(0,1fr) auto auto}
.compose .sec{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:18px 20px;display:grid;gap:16px;margin:0 0 16px}
.compose .sec>h2{font-size:16px}
.compose .sec>.hint-line{margin:-10px 0 0}
.compose .slots{background:var(--surface-2);border:0}
.field small{color:var(--muted);font-size:12px;margin-top:-4px;text-wrap:pretty}/* Fix-round B-45: a form helper line never leaves one word alone ("…appear here" / "too" under Quest category at 320px). Was: no text-wrap. */
.field input[type=datetime-local]{width:100%;min-height:44px;border:1px solid var(--line-strong);border-radius:8px;background:#fff;padding:9px 11px}
.grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px 16px}
.grid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:14px 16px;align-items:start}
/* Fix-round B-41: in the event and quest forms the date-time boxes never run past the card or over each other: two to a row only
   while each gets 220px, else one to a row. "วิธีรับผู้ร่วม" takes the whole row, its helper line under the choice; the other boxes
   of that row close up (dense). Was: two fixed columns (the datetime box stuck out past the card) and a third-width choice cut to
   "เจ้าหน้าที่คัด" with its helper broken mid-word above it. */
.grid2:has(>.field>input[type=datetime-local]){grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr))}
.field input[type=datetime-local]{min-width:0;max-width:100%}
.grid3:has(>.field>select[name=selection]){grid-auto-flow:row dense}
.grid3>.field:has(>select[name=selection]){grid-column:1/-1}
.grid3>.field:has(>select[name=selection])>small{order:1;margin-top:0}
.check{display:flex;align-items:flex-start;gap:10px;font-size:15px;cursor:pointer}
.check input{width:20px;height:20px;margin-top:4px;accent-color:var(--primary);flex:none}
.check span{display:grid}
.check small{font-size:13px;color:var(--wait)}
.check input:disabled+span{color:var(--muted);cursor:not-allowed}
.compose .checks{display:flex;flex-wrap:wrap;gap:8px 22px}
/* Owner 7 Nov 2026 (fix round, FX2-09): a quest with sign-ups shows its class, category and evidence ticks as chosen but locked, with the
   locked line close under the group (as under a locked field); only the chosen class keeps its colour. */
.compose .sec>.locked-note{display:block;margin:-10px 0 0;color:var(--muted);font-size:12px;text-wrap:pretty}
.ranks:disabled label{cursor:not-allowed}
.ranks:disabled label:not(:has(input:checked)){opacity:.55}
.qcat-locked{color:var(--muted);cursor:not-allowed}
.qcat-static{display:flex;align-items:center;gap:10px;min-height:44px;padding:9px 11px}
.langs{border-top:1px solid var(--line);padding-top:12px}
.langs summary{cursor:pointer;font-size:14px;font-weight:500;min-height:36px;display:flex;align-items:center}
.langs fieldset{border:0;padding:0;margin:12px 0 0;display:grid;gap:12px}
.langs legend{font-size:13px;color:var(--muted);margin-bottom:6px}
.ranks{border:0;margin:0;padding:0;display:grid;grid-template-columns:repeat(6,minmax(0,1fr));gap:8px}
.ranks legend{font-size:14px;margin-bottom:8px;padding:0}
.ranks label{position:relative;display:grid;gap:2px;align-content:start;padding:10px 10px 12px;border:1px solid var(--line-strong);border-radius:10px;cursor:pointer;min-height:96px}
.ranks input{position:absolute;opacity:0;pointer-events:none}
.ranks b{font-size:22px;line-height:1.2;color:var(--t-quests)}
.ranks small{font-size:12px;color:var(--muted);line-height:1.45}
.ranks label:has(input:checked){border-color:var(--t-quests);background:var(--t-quests-bg);box-shadow:0 0 0 1px var(--t-quests) inset}
.ranks label:has(input:focus-visible){outline:2px solid var(--focus);outline-offset:2px}
.cover-picks{display:grid;grid-template-columns:repeat(auto-fill,minmax(84px,1fr));gap:8px}
.cover-picks button{aspect-ratio:4/5;border-radius:9px;border:2px solid transparent;background:#222 center/cover;cursor:pointer}
.cover-picks button.none{background:var(--surface-2);color:var(--muted);font-size:12px;padding:6px;border-color:var(--line)}
.cover-picks button[aria-pressed=true]{border-color:var(--primary);box-shadow:0 0 0 2px #fff inset}
.post-preview{border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--surface)}
.pp-art{position:relative;aspect-ratio:16/10;background:#222 center/cover}
.pp-art.none{display:grid;place-items:center;background:var(--surface-2);color:var(--muted);font-size:13px}
.pp-flag{position:absolute;left:8px;top:8px;font-size:12px;padding:2px 9px;border-radius:999px;background:var(--primary);color:var(--primary-ink)}
.pp-copy{display:grid;gap:2px;padding:10px 12px 12px}
.pp-copy strong{font-weight:600;line-height:1.5}
.pp-copy small{color:var(--muted);font-size:12px}
.pp-copy p{margin:4px 0 0;font-size:13px;color:var(--muted);display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.missing .notice{margin:0}

/* Real-page previews: the sign-in page and member posts, framed at device size */
.live{position:relative;overflow:hidden;border:1px solid var(--line);border-radius:14px;background:#000}
.live iframe{position:absolute;left:0;top:0;border:0;transform-origin:0 0;pointer-events:none}
.live.phone{width:195px;height:422px}
.live.phone iframe{width:390px;height:844px;transform:scale(.5)}
.live.desk{width:100%;max-width:448px;aspect-ratio:16/10}
.live.desk iframe{width:1280px;height:800px;transform:scale(.35)}
.pv{position:fixed;inset:0;z-index:20;display:grid;grid-template-rows:auto minmax(0,1fr);background:#17191cf2;color:var(--rail-ink)}
.pv-bar{display:flex;flex-wrap:wrap;align-items:center;gap:10px 16px;padding:12px 20px;border-bottom:1px solid var(--rail-line)}
/* Owner 7 Nov 2026 (fix round, FX4-40; the QA's suggestion, no owner rule): the bar has the frame's colour, solid, so the page under the preview
   (its logo, menus and words) no longer shows faintly through behind the heading and its note on a phone. Was: no background (the frame's 95%). */
.pv-bar{background:var(--rail)}
.pv-note{font-size:13px;color:var(--rail-muted);margin-right:auto}
.pv-seg{display:flex;gap:2px;padding:3px;border-radius:10px;background:var(--rail-2)}
/* Next chat (NEXT-CHAT-TODO ข5, FX5-16): the Phone / Computer buttons are as tall as "ปิดตัวอย่าง" (44 px) on a computer too, as on phones. Was: 38 px at 1366. */
.pv-seg button{min-height:44px;padding:4px 14px;border:0;border-radius:8px;background:transparent;color:var(--rail-muted);cursor:pointer}
.pv-seg button[aria-pressed=true]{background:var(--rail-ink);color:var(--rail)}
.pv-bar .btn{min-height:40px}
.pv-stage{position:relative;display:grid;place-items:center;overflow:auto;padding:20px}
.pv-device{background:#000;border-radius:28px;overflow:hidden;box-shadow:0 0 0 8px #2a2d31,0 24px 60px #0008}
.pv-device iframe{display:block;border:0;width:100%;height:100%}
.pv-device.phone{width:390px;height:min(844px,calc(100dvh - 120px))}
.pv-device.desk{width:min(1280px,calc(100vw - 40px));height:min(800px,calc(100dvh - 120px));border-radius:12px}
.pv-status{position:absolute;left:0;right:0;bottom:8px;margin:0;text-align:center;font-size:14px;color:var(--rail-muted)}
@media (max-width:900px){
 .pv-bar{padding:10px 12px}
 .pv-stage{padding:10px}
 .pv-device.phone{width:100%;height:calc(100dvh - 150px);border-radius:16px}

 .side{position:static}
 .post-row{grid-template-columns:max-content minmax(0,1fr) auto;grid-template-areas:'time what go' 'time what go'}
 /* Fix round 11 Nov 2026 (item 151): the form's button panel stays under the sticky header (.top, z-index 5) when scrolled to the end. Was: z-index 6 from the bottom-sheet rule, so on a grid it covered the header. */
 .compose+.dock{position:static;z-index:auto;border-radius:14px;max-height:none;box-shadow:none;margin-bottom:24px}
 .compose+.dock>h2{display:block}
 .compose .sec{padding:16px}
 .grid2,.grid3{grid-template-columns:minmax(0,1fr)}
 .ranks{grid-template-columns:repeat(3,minmax(0,1fr))}
 .head-actions{width:100%}
 .head-actions .btn{flex:1}

 .sc{grid-template-columns:minmax(0,1fr)}
 .rail{display:none}
 .top{padding:10px 16px;gap:10px;flex-wrap:wrap}
 .top .brand-m{display:flex;align-items:center;gap:8px;font-weight:600}
 .top .brand-m .wordmark{width:92px;color:var(--ink,#1d2124)}
 .top .who-m{margin-left:auto}
 /* Fix-round B-42 (owner 31 Oct): the duty switch ("ฝ่ายการเงิน" / "Finance" / "财务") stays on the TOSAA row in every language; the
    box is never wider than the room left beside the wordmark. Was: in English its longest option ("Applications, identity and
    recovery") made it too wide, so it dropped under TOSAA. */
 .top .who-m{flex:0 1 auto;min-width:0;max-width:calc(100% - 102px)}
 .top .who-m select{max-width:100%;text-overflow:ellipsis}
 /* Owner answer Q-2 (2 Nov 2026, B-42): the box shows the short name (.who-short) and its size; the select lies over it, unseen, so a tap
    opens the list of full names. Was: the select showed the full name, cut with … inside a word. */
 .top .who-m{position:relative;display:flex}
 .top .who-short{display:flex;align-items:center;gap:8px;min-height:42px;padding:0 10px;border:1px solid var(--line);border-radius:8px;background:var(--surface);white-space:nowrap;line-height:1.2}
 .top .who-short::after{content:"";flex:none;width:7px;height:7px;margin:-4px 2px 0 2px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg)}
 .top .who-m select{position:absolute;inset:0;width:100%;height:100%;max-width:none;opacity:0;cursor:pointer}
 .top .who-m:focus-within .who-short{outline:2px solid var(--focus);outline-offset:2px}
 /* Review fix (2 Nov 2026, DEF-B-42): safety net, the box can never widen the page; the short duty names fit, a longer text is cut at its end. */
 .top .who-short{min-width:0;max-width:100%;overflow:hidden}
 .top .who-short-text{min-width:0;overflow:hidden;text-overflow:ellipsis}
 .top .search{order:3;max-width:none;flex-basis:100%}
 .top .date,.top .lang-wide{display:none}
 .page{padding:18px 16px 140px}
 .row{grid-template-columns:64px minmax(0,1fr);grid-template-areas:'time what' 'time meta';/* Owner 26 Oct 2026. Was: 64px 1fr auto with a go cell */gap:6px 12px;padding:12px 2px}
 /* Fix round 11 Nov 2026 item 150 (re-check 12 Nov): a post row's date column is as wide as its whole date. Was: 64px, and "9 ต.ค. 2026" or "2026年11月29日" ran onto the title. */ .row.post-row{grid-template-columns:max-content minmax(0,1fr)}
 .row .what strong{white-space:normal;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
 .row .tagcell{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
 .row .tagcell .row-due{display:inline-flex;margin-top:0}/* FX4-44 */
 .m-only{display:inline-flex}
 .row .time{grid-area:time;align-self:start;white-space:nowrap}.row .what{grid-area:what}.row .tagcell{grid-area:meta}.row>.state{display:none}
 .work{grid-template-columns:minmax(0,1fr)}
 .dock{position:fixed;left:0;right:0;bottom:64px;top:auto;border-radius:16px 16px 0 0;max-height:58dvh;overflow:auto;z-index:6;padding:14px 16px calc(14px + env(safe-area-inset-bottom));box-shadow:0 -10px 28px #1d212426}
 .dock.collapsed>*:not(.dock-toggle){display:none}
 /* QA 16 Oct 2026: an open bottom sheet hid the end of the item; leave room to scroll everything above it. */
 .page:has(.dock:not(.collapsed)){padding-bottom:calc(58dvh + 96px)}
 .page:has(.dock.collapsed){padding-bottom:150px}
 /* Fix round 11 Nov 2026 (item 208, owner took the suggestion): a control reached with the keyboard scrolls clear of the bars fixed at the
    bottom (the menu bar, and the panel lowered or raised). Was: the page did not move, so the focused row sat under the menu bar. */
 html{scroll-padding-bottom:84px}html:has(.dock.collapsed){scroll-padding-bottom:156px}html:has(.dock:not(.collapsed)):not(:has(.compose+.dock)){scroll-padding-bottom:calc(58dvh + 84px)}
 /* Owner 7 Nov 2026 (fix round, Q2-Q7): with คำถามที่พบบ่อย and เอกสารต้นแบบ now lowered on arrival, the result of a button in the page
    (เลื่อนแล้วในร่าง, บันทึกลงร่างแล้ว …) still reads under the lowered bar's title instead of hiding inside the folded panel; the page leaves
    room for it. Was: every part of a lowered panel but its bar was hidden, the result too. */
 .dock.collapsed>.result{display:block;margin:2px 0 0}
 .page:has(.dock.collapsed>.result){padding-bottom:200px}
 .dock-toggle{display:flex!important}
 /* QA B-34 (owner 31 Oct 2026): the hide button is clear and easy to tap: it stays at the top of the panel while the panel scrolls, on
    the panel's own surface with a line under it. (Its "ซ่อน" / "แสดง" pill was taken out on 7 Nov 2026, Q2-S-01, below.) */
 .dock>.dock-toggle{position:sticky;top:-14px;z-index:2;gap:12px;width:calc(100% + 32px);min-height:52px;margin:-14px -16px 0;padding:4px 16px;background:var(--surface);border-bottom:1px solid var(--line);border-radius:16px 16px 0 0}
 .dock.collapsed .dock-toggle{border-bottom:0}
 .dock-toggle-title{min-width:0;text-align:left}
 /* Owner 7 Nov 2026 (fix round, Q2-S-01: "ไม่ต้องมีคำว่าซ่อน ให้พื้นดำๆมนๆก็ไม่ต้องมี เอาให้มีแค่ลูกศร v พอ"): only the arrow, in the ink colour, at
    the right of the bar; the whole bar stays the button. Was: .dock-toggle-act{…;gap:6px;min-height:40px;padding:0 12px 0 14px;
    border-radius:999px;background:var(--ink);color:#fff;font-size:14px;font-weight:500} with "ซ่อน" / "แสดง", and an 18px arrow. */
 .dock-toggle-act{flex:none;display:inline-grid;place-items:center;width:44px;height:44px;margin-right:-10px;color:var(--ink)}
 .dock-toggle-act svg.i{width:24px;height:24px;stroke-width:2}
 .dock>h2{display:none}
 .tabbar{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;position:fixed;left:0;right:0;bottom:0;z-index:7;background:var(--rail);color:var(--rail-ink);padding:4px 6px calc(4px + env(safe-area-inset-bottom))}
 /* Fix round 11 Nov 2026 item 146: an open panel ("แนบสลิป", "กฎที่จำไว้") stays under the bottom tab bar (z-index 7) on a phone, above the sticky
    header (5). Was: z-index 20, so the panel covered the tab bar at 320 px. */
 details.pop>.pop-panel{z-index:6}
 .tabbar a{display:grid;justify-items:center;gap:2px;min-height:56px;padding:6px 0;font-size:11px;text-decoration:none;color:var(--rail-muted);border-radius:10px}
 .tabbar a[aria-current=page]{color:var(--rail-ink);background:#ffffff12}
 dl.facts{grid-template-columns:minmax(0,1fr)}
 dl.facts dt{padding-bottom:0;border-bottom:0}
 .frames{grid-template-columns:minmax(0,1fr)}
 .frame.phone{max-width:220px}
 .sheet-head{flex-direction:column;align-items:flex-start;gap:6px}
 .sheet-head h1{font-size:20px}.sheet-head.duties-head h1{font-size:22px}/* item 140. Was: 22px for every page without a back arrow */
}
.dock-toggle{display:none;align-items:center;justify-content:space-between;width:100%;min-height:44px;border:0;background:transparent;font-weight:600;cursor:pointer;padding:0}
/* Owner 26 Oct 2026: open panel, arrow down; lowered panel, arrow up. Was: up in both states. */
.dock-toggle[aria-expanded=true] svg{transform:rotate(180deg)}
@media (min-width:901px){.top .brand-m,.top .who-m{display:none}}
@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}
/* Owner decisions 16 Oct 2026 (governance-ui.js): plain list rows for requests, accounts, notices and categories. */
.gov-item{display:flex;flex-wrap:wrap;align-items:center;gap:8px 14px;min-height:56px;padding:10px 4px;border-bottom:1px solid var(--line);color:inherit;text-decoration:none}
a.gov-item:hover strong,a.gov-item:focus-visible strong{text-decoration:underline;text-underline-offset:4px}
a.gov-item[aria-disabled="true"]{pointer-events:none}
.gov-item .what{flex:1 1 220px;min-width:0}
/* Fix round 11 Nov 2026 item 147: a row link (การเงินสมาคม and the other lists with an <a class="what">) has no underline, as the other staff
   lists; the title underlines on hover. Was: the browser's link underline on every line of the row. */
.gov-item a.what{color:inherit;text-decoration:none}
.gov-item a.what:hover strong,.gov-item a.what:focus-visible strong{text-decoration:underline;text-underline-offset:4px}
.gov-item .what strong{display:block;font-weight:500;overflow-wrap:anywhere}
.gov-item .what small{display:block;font-size:13px;color:var(--muted);overflow-wrap:anywhere}
.gov-row-actions{display:flex;flex-wrap:wrap;gap:8px}
.gov-row-actions .btn,.gov-item>.btn{min-height:44px}
.gov-inline{display:flex;flex-wrap:wrap;align-items:flex-end;gap:8px 10px;flex:1 1 100%}
.gov-inline .field{flex:1 1 160px;margin:0}
.gov-inline select{min-height:44px}
/* Step 7 stage S4: an Honorary member's creator roles, each staff-opened one with its own close button. */
.gov-hon-roles{list-style:none;margin:6px 0 0;padding:0;display:grid;gap:6px}
.gov-hon-roles li{display:flex;flex-wrap:wrap;align-items:center;gap:6px 10px}
.gov-item .what .gov-hon-roles small{display:inline}
.gov-item .gov-hon-blocked{flex:1 1 100%;font-size:13px;color:var(--wait)}
.gov-hon-form .field,.gov-faq-form .field{flex:1 1 100%}
/* Fix round 11 Nov item 160: on a computer the line under the reason has its own row, and บันทึก and ยกเลิก sit side by side under it (as at 390 px). Was: the line shared a row with บันทึก and ยกเลิก dropped to the next row. */
.gov-hon-form>.consequence{flex:1 1 100%;margin:0}
/* Fix round 11 Nov 2026 finding 255 (owner 13 Nov 2026 "ก"): the "แก้ของ: [name]" line above บันทึก takes its own row. Was: no such line */
.gov-hon-form>.gov-hon-for{flex:1 1 100%;margin:0;font-size:14px}
.gov-acct form{margin-top:10px}
/* Owner 29 Oct 2026: one จัดการ button per staff account opens a panel in labelled parts; each part's buttons sit in one row. */
.gov-acct-panel{flex:1 1 100%;outline:none;margin:4px 0 6px;padding:2px 16px;border:1px solid var(--line);border-radius:14px;background:var(--surface)}
.gov-acct-part{padding:14px 0}
.gov-acct-part+.gov-acct-part{border-top:1px solid var(--line)}
.gov-acct-part h3{margin:0 0 6px;font-size:14px;font-weight:600}
.gov-acct-note{margin:0 0 4px;text-wrap:pretty}/* on top of .hint-line */
.gov-acct-btns{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.gov-acct-btns+.gov-acct-note{margin-top:16px}/* QA S-10: a second action in one part (ส่งลิงก์ตั้งรหัสผ่านใหม่ under ออกจากระบบทุกเครื่อง) starts with room */
.gov-acct-btns .btn{min-height:44px}
/* Owner 7 Nov 2026 (fix round, Q2-B-24: "แถวเดียวกัน แต่ปุ่มอย่าติดกันนะ"): ถอดจากผู้ดูแลระบบ and ยกเลิก stay in one row in every language down to
   320px (owner 29 Oct 2026 evening, item 4), still 8px apart; the labels never wrap and the buttons are a little narrower on a small phone.
   Was: the row wrapped, so "Remove as admin" and "Cancel" took two rows in English at 320px. */
form[data-form=gov-demote] .gov-acct-btns{flex-wrap:nowrap}
form[data-form=gov-demote] .gov-acct-btns .btn{white-space:nowrap}
@media (max-width:400px){form[data-form=gov-demote] .gov-acct-btns .btn{padding-inline:12px}}
/* Owner 7 Nov 2026 (fix round, BUG-11): a result in a person's panel, and "ส่งลิงก์เชิญแล้ว", scroll clear of the sticky header (two rows,
   115px, on a phone or tablet), with the part's heading above it in view, and of the lowered add-staff bar and the tab bar at the bottom,
   so the result is seen where it is said. Was: no margin, so block:'nearest' left "ตั้งเป็นผู้ดูแลระบบแล้ว" under the header and
   "เปิดบัญชีแล้ว" under the bottom bars at 390px. */
.gov-acct-panel [data-gov-acct-msg],[data-gov-invite-sent]{scroll-margin:104px 0 24px}
@media (max-width:900px){.gov-acct-panel [data-gov-acct-msg],[data-gov-invite-sent]{scroll-margin:152px 0 140px}}
/* Owner 7 Nov 2026 (fix round, FX4-45, re-check): a refused Honorary invitation's message scrolls clear of the sticky header on a computer
   (governance-ui.js honoraryRefused), and clear of the bar at the top of the panel's sheet on a phone or tablet, where the panel scrolls on
   its own. Was: no margin (on a computer the message stayed above the screen). */
.dock:has(form[data-form=gov-honorary])>.result{scroll-margin:104px 0 24px}
@media (max-width:900px){.dock:has(form[data-form=gov-honorary])>.result{scroll-margin:64px 0 16px}}
/* Fix round 11 Nov 2026 item 252 (independent re-check 12 Nov): an Honorary member whose "แก้สถานะนักแสดง" form opens below the screen scrolls to just under the sticky header (governance-ui.js), as the account messages above. Was: no margin; the form was scrolled up by its bottom only (42 px at 1366×768), leaving the page title and back arrow half under the header. */
.gov-hon[data-hon-member]{scroll-margin-top:104px}
/* Fix round 11 Nov 2026 item 252 (independent re-check 12 Nov): the taller wrapped header on a phone or tablet. Was: no margin. */
@media (max-width:900px){.gov-hon[data-hon-member]{scroll-margin-top:152px}}
.gov-acct-panel form{margin-top:4px}
.gov-acct.open{border-bottom-color:transparent}
.gov-acct-panel .gov-duties>legend{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}/* the part's h3 already says หน้าที่ */
.gov-duties{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:6px 12px}
.gov-duties label{display:flex;align-items:center;gap:8px;min-height:44px}
.gov-slide legend{font-weight:600;padding:0 4px}
.gov-slide-art{aspect-ratio:3/2;max-width:320px;border-radius:10px;background:var(--line) center/cover no-repeat;margin-bottom:12px}
.field input[type=email],.field input[type=number],.field input[type=password]{width:100%;min-height:44px;border:1px solid var(--line-strong);border-radius:8px;background:#fff;padding:9px 11px;font:inherit;color:inherit}
/* Staff sign-in, invitation and app lock (owner decision 16 Oct 2026, Q23). */
.signin-page{min-height:100dvh;display:grid;place-items:center;padding:24px 16px}
.signin{width:min(440px,100%)}
.signin-card{background:var(--surface);border:1px solid var(--line);border-radius:16px;padding:26px 24px}
.signin-card h1{font-size:24px;margin:10px 0 4px}
.signin-card h1:focus{outline:none}
.signin-card form{display:grid;gap:14px;margin-top:16px}
.signin-card .btn.full+.btn.full,.signin-card form+.btn.full{margin-top:10px}
/* Fix round 11 Nov item 142: the lock page's "ออกจากระบบบนเครื่องนี้" sat right under the help line (0 px); it gets the gap the other buttons have. */
.signin-card .signin-help+.btn.full{margin-top:10px}
.signin-brand{display:flex;align-items:center;gap:10px;color:var(--muted);font-size:13px}
.signin-brand .wordmark{width:104px;color:var(--ink,#1d2124)}
.signin-sub,.signin-help{color:var(--muted);font-size:14px;margin:4px 0 0}
/* Fix round 11 Nov 2026 (item 206): the step line of a first sign-in, under the brand. */
.signin-step{margin:2px 0 -6px;font-size:13px;font-weight:600;color:var(--muted)}
.signin-card .pin{letter-spacing:.4em;font-size:20px;text-align:center}
.signin-otp{display:grid;grid-template-columns:120px minmax(0,1fr);gap:14px;align-items:center}
.signin-card-art{margin:16px 0 12px}
.signin-facts{margin:12px 0 0}
.signin-facts dt{color:var(--muted);font-size:13px}
.signin-facts dd{margin:0 0 8px;font-size:15px;overflow-wrap:anywhere}
/* QA S-10: ลืมรหัสผ่าน and กลับไปหน้าเข้าสู่ระบบ are links with a full-size tap area. */
.signin-link{display:inline-block;padding:11px 0;margin:-11px 0;color:var(--ink);text-decoration:underline;text-underline-offset:3px}
/* QA S-07: inside the console's window the page starts below the window's ปิด button, so the button never covers the card. */
html.framed body.signin-page{padding-top:62px}
/* QA S-07 (FIX-LIST 31 Oct 2026): the honorary member's link has the member app's look (registration/claim.html colours and shapes). */
html.member-look,html.member-look body{background:#191919;color:#f2efe9}
.member-look .signin-card{background:#222;border-color:#ffffff2e;color:#f2efe9}
.member-look .signin-brand,.member-look .signin-sub,.member-look .signin-help,.member-look .signin-facts dt{color:#bdb8ae}
.member-look .signin-brand .wordmark{color:#f2efe9}
.member-look .field input[type=password],.member-look .field input[type=text]{background:#111;color:#f2efe9;border-color:#ffffff52;border-radius:10px;min-height:48px}
.member-look .btn{min-height:48px;border-radius:24px;background:transparent;color:#f2efe9;border-color:#ffffff52}
.member-look .btn.primary{background:#f2efe9;color:#191919;border-color:#f2efe9}
.member-look .pw-eye{color:#bdb8ae}.member-look .pw-eye.on{color:#f2efe9}
.member-look .result.err{background:#3a1f1b;color:#ff9b8a}.member-look .result.ok{background:#1e3322;color:#9fd8a8}
.member-look :focus-visible{outline:2px solid #f2efe9;outline-offset:3px}
/* Owner answer Q-4 (2 Nov 2026, S-07): the two sign-up tick boxes and the terms window of the member claim page (registration/claim.html). */
.member-look .signup-legal{display:grid;gap:14px;margin:4px 0 16px}.member-look .legal-draft{font-size:12px;color:#bdb8ae;margin:0}
.member-look label.legal-check{display:flex;align-items:flex-start;gap:12px;margin:0;font-size:15px;cursor:pointer}
.member-look .legal-check input{width:22px;height:22px;min-height:22px;flex:0 0 22px;margin:2px 0 0;padding:0;accent-color:#f2efe9;cursor:pointer}
.member-look .legal-check input[aria-invalid=true]{outline:2px solid #ff9b8a;outline-offset:2px}
.member-look .legal-check .btn{display:inline;width:auto;min-height:0;padding:11px 2px;margin:-11px 0;border:0;border-radius:4px;background:none;color:#f2efe9;font:inherit;font-weight:400;text-decoration:underline;text-underline-offset:3px}
.member-look .legal-dialog{max-width:560px;width:calc(100% - 32px);max-height:85svh;padding:20px;border:1px solid #ffffff2e;border-radius:16px;background:#222;color:#f2efe9;overflow:auto}
.member-look .legal-dialog::backdrop{background:#000c}.member-look .legal-dialog header{display:flex;align-items:center;justify-content:space-between;gap:12px}.member-look .legal-dialog .eyebrow{font-size:12px;color:#bdb8ae;margin:0}.member-look .legal-dialog h2{font-size:22px;line-height:1.3;margin:14px 0 8px}.member-look .legal-dialog h3{font-size:16px;margin:18px 0 6px}.member-look .legal-dialog p{font-size:14px}.member-look .legal-dialog .legal-draft{padding:10px;border:1px dashed #ffffff2e;border-radius:10px}
.signin-overlay{width:min(480px,calc(100% - 24px));height:min(760px,calc(100dvh - 24px));padding:0;border:0;border-radius:18px;background:var(--ground);overflow:hidden}
.signin-overlay::backdrop{background:#000a}
.signin-overlay iframe{width:100%;height:100%;border:0}
/* Owner 7 Nov 2026 (fix round, Q2-B-01): a round cross button on the old button's surface, so it shows on the staff pages and on the dark Honorary link. Was: the .btn "ปิด" text button at the same place. */
.signin-overlay-close{position:absolute;top:10px;right:10px;z-index:1;display:grid;place-items:center;width:44px;height:44px;padding:0;border:1px solid var(--line-strong);border-radius:999px;background:var(--surface);color:var(--ink);cursor:pointer}
.signin-overlay-close:hover{background:var(--surface-2)}
.signin-overlay-close svg.i{width:22px;height:22px}
.signin-overlay-close[hidden]{display:none}
/* Owner 26 Oct 2026: after sign-out the sign-in page is the whole screen, not a window over the app. */
.signin-overlay.signin-page{width:100%;height:100dvh;max-width:none;max-height:none;margin:0;border-radius:0}
.signin-overlay.signin-page::backdrop{background:var(--ground)}
.signout-ask{width:min(400px,calc(100% - 32px));padding:22px;border:0;border-radius:18px;background:var(--ground);color:inherit}
.signout-ask::backdrop{background:#000a}
.signout-ask h2{margin:0 0 6px;font-size:20px}
.signout-ask p{margin:0 0 18px;color:var(--muted);font-size:14px}
.signout-ask .head-actions .btn{flex:1}
/* Owner 7 Nov 2026 (fix round, Q2-B-25: "ทำให้อยู่ในบรรทัดเดียวให้ได้"): a pop-up's two buttons stay side by side (FIX-LIST item 1) and each
   label stays on one line in every language down to 320px ("ออกจาก / ระบบ", "ตั้งเป็นผู้ / ดูแลระบบ", "Make / admin", "设为系统 / 管理员",
   "Discard / draft"): equal halves (flex:1) while both labels fit, else the longer label keeps its whole width and the shorter one takes
   the rest (a flex item is never narrower than its unbroken label); a small phone has a little less padding. Only a pair too long for
   the screen side by side would take a row each, never a broken label. Was: labels could wrap, so a long one broke inside a half. */
.signout-ask .head-actions .btn{white-space:nowrap}
@media (max-width:400px){.signout-ask{padding:20px 18px}.signout-ask .head-actions .btn{padding-inline:12px}}
@media(max-width:420px){.signin-otp{grid-template-columns:1fr}}
/* Check-in by QR (owner decision 16 Oct 2026, Q9). */
.checkin-camera video{display:block;width:100%;max-width:420px;aspect-ratio:1;object-fit:cover;border-radius:12px;background:#111}
.checkin-camera{margin-bottom:12px}
.checkin-result{padding:16px;border:1px solid var(--line-strong);border-radius:14px;background:var(--surface)}
.checkin-result h2:focus{outline:none}
.checkin-person{display:flex;align-items:center;gap:16px;margin:8px 0}
/* QA B-38 (FIX-LIST section 1 item 9): the profile photo is a 4:5 frame (96x120) that never shrinks; the person icon sits centred inside it,
   under the photo, so with no photo it shows in the empty frame and never over the name or the state; the text column wraps beside it.
   Was: .checkin-person img{width:96px;height:96px} (square), no frame of its own. */
.checkin-photo{position:relative;flex:none;display:grid;place-items:center;width:96px;aspect-ratio:4/5;border-radius:12px;overflow:hidden;background:var(--line);color:var(--muted)}
.checkin-photo>svg.i{width:44px;height:44px;fill:none;stroke:currentColor;stroke-width:1.6}
.checkin-photo>img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.checkin-photo>img[hidden]{display:none}
.checkin-person>div{display:flex;flex-direction:column;gap:4px;align-items:flex-start;min-width:0;flex:1 1 auto;overflow-wrap:anywhere}
@media (max-width:360px){.checkin-person{gap:12px}.checkin-photo{width:80px}}
.checkin-person strong{font-size:18px;font-weight:600}
.checkin-steps{margin:0;padding-left:20px;display:grid;gap:8px}
/* Quest category picker: icons for every category, main categories bold at the edge, sub-categories one step in (owner feedback 16 Oct 2026). */
.qcat{border:1px solid var(--line-strong);border-radius:8px;background:#fff}
.qcat summary{list-style:none;display:flex;align-items:center;gap:10px;min-height:44px;padding:9px 11px;cursor:pointer}
.qcat summary::-webkit-details-marker{display:none}
.qcat summary:focus-visible{outline:2px solid var(--focus);outline-offset:2px;border-radius:8px}
.qcat-chosen{flex:1;display:flex;align-items:center;gap:10px;min-width:0}
.qcat-placeholder{color:var(--muted)}
.qcat-chevron{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;flex:none;transition:transform .15s}
.qcat[open] .qcat-chevron{transform:rotate(180deg)}
.qcat svg:not(.qcat-chevron){width:22px;height:22px;flex:none;color:var(--t-quests)}
.qcat-list{border:0;border-top:1px solid var(--line);margin:0;padding:6px 0;max-height:380px;overflow:auto}
.qcat-group+.qcat-group{border-top:1px solid var(--line);margin-top:4px;padding-top:4px}
.qcat-main,.qcat-sub{display:flex;align-items:center;gap:10px;min-height:44px;padding:6px 12px;margin:0 4px;border-radius:8px}
.qcat-main{font-weight:700}
.qcat-sub{padding-left:46px;font-weight:400}
.qcat-option{cursor:pointer}
.qcat-option input{position:absolute;opacity:0;pointer-events:none}
.qcat-option:hover{background:var(--t-quests-bg)}
.qcat-option:has(input:checked){background:var(--t-quests-bg);box-shadow:inset 3px 0 0 var(--t-quests)}
.qcat-option:has(input:focus-visible){outline:2px solid var(--focus);outline-offset:-2px}
/* Quest category settings: same icons and indent as the quest form picker (owner decision 16 Oct 2026). */
.gov-cat-head{display:flex;align-items:center;gap:10px}
.gov-cat-head svg,.gov-cat>svg{width:22px;height:22px;flex:none;color:var(--t-quests)}
.gov-cat{padding-left:32px}
.gov-cat>.what{flex:1;min-width:0}
/* TOSAA wordmark: letters only on a fully transparent ground, in the text colour (owner feedback 16 Oct 2026: the logo showed a
   square box when content scrolled under the frosted header). The small subtitle is left out, as the owner allowed. */
.wordmark{display:block;flex:none;aspect-ratio:755/181;background:currentColor;-webkit-mask:url('/actors-profile-and-industry-pov/assets/tosaa-wordmark.png') center/contain no-repeat;mask:url('/actors-profile-and-industry-pov/assets/tosaa-wordmark.png') center/contain no-repeat}
@media(forced-colors:active){.wordmark{background:CanvasText}}
/* Live event/quest management in the compose dock (moved from the UI06 preview, owner decision 16 Oct 2026). */
.lifecycle{border-top:1px solid var(--line);margin-top:14px;padding-top:12px;display:grid;gap:8px}
.lifecycle h3{font-size:14px;margin:0}
.lifecycle details{border:1px solid var(--line-strong);border-radius:8px;background:#fff}
.lifecycle summary{min-height:44px;display:flex;align-items:center;padding:0 12px;cursor:pointer;font-weight:600}
.lifecycle form{display:grid;gap:10px;padding:4px 12px 12px}
.rev-picker{display:flex;flex-wrap:wrap;gap:8px;margin:4px 0 10px}
/* A member's completed quests inside the evidence review */
.mq-total{margin:0 0 10px;color:var(--muted)}.mq-total strong{font-size:22px;color:var(--fg,inherit);margin-right:2px}
.mq-cats{list-style:none;margin:0 0 10px;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:6px}
.mq-cats li{display:flex;align-items:center;gap:8px;padding:8px 10px;border:1px solid var(--line);border-radius:8px;background:var(--surface);font-size:13px;min-width:0}
.mq-cats li span{flex:1;min-width:0;overflow-wrap:break-word;text-wrap:balance}/* Final polish round 3 T2: a 170 px tile holds "Communication" whole; a category name wraps between words, in balanced lines (no lone "records" or "制作"). */.mq-cats li svg{width:18px;height:18px;flex:none}
.mq-cats li.zero{opacity:.55}
.mq-recent{list-style:none;margin:0;padding:0;display:grid;gap:4px}.mq-recent li{display:flex;gap:10px;justify-content:space-between;padding:6px 0;border-bottom:1px solid var(--line)}.mq-recent small{color:var(--muted);flex:none}

/* ---------- Member overview (registry-ui.js). Theatre vocabulary: a marquee sign, a seat plan, ticket stubs. ---------- */
.ov-marquee{position:relative;margin:0 0 20px;padding:20px 24px;border-radius:14px;background:var(--rail);color:var(--rail-ink);overflow:hidden}
.ov-marquee::before{content:'';position:absolute;inset:5px;border-radius:10px;pointer-events:none;opacity:.9;
 background:radial-gradient(circle,#f3d27e 0 1.5px,#f3d27e33 2.4px,transparent 3px) 0 0/14px 7px repeat-x,radial-gradient(circle,#f3d27e 0 1.5px,#f3d27e33 2.4px,transparent 3px) 0 100%/14px 7px repeat-x,
 radial-gradient(circle,#f3d27e 0 1.5px,#f3d27e33 2.4px,transparent 3px) 0 0/7px 14px repeat-y,radial-gradient(circle,#f3d27e 0 1.5px,#f3d27e33 2.4px,transparent 3px) 100% 0/7px 14px repeat-y;
 animation:ov-chase 3.6s linear infinite}
@keyframes ov-chase{to{background-position:14px 0,-14px 100%,0 -14px,100% 14px}}
.ov-marquee dl{position:relative;margin:0;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px 18px}
.ov-marquee dt{font-size:12px;color:var(--rail-muted)}
.ov-marquee dd{margin:0;font-size:34px;font-weight:600;line-height:1.15;letter-spacing:-.01em}
.ov-marquee dd small{font-size:13px;font-weight:500;color:#f3d27e;margin-left:6px;letter-spacing:0}
.ov-views{display:flex;gap:4px;overflow-x:auto;margin:0 0 18px;border-bottom:1px solid var(--line);scrollbar-width:none}
.ov-views a{display:inline-flex;align-items:center;gap:8px;min-height:44px;padding:0 14px;white-space:nowrap;text-decoration:none;color:var(--muted);border-bottom:3px solid transparent;margin-bottom:-1px;font-size:14px}
.ov-views a span{font-size:12px;padding:1px 8px;border-radius:999px;background:var(--surface-2);color:var(--ink)}
.ov-views a[aria-current=page]{color:var(--ink);font-weight:600;border-bottom-color:var(--ink)}
/* Fix round 11 Nov item 161: on a phone the four type tabs wrap onto a second row, so กิตติมศักดิ์ is seen without swiping (as the sub-tabs of วิสามัญ). Was: one row that scrolled sideways with nothing showing more tabs. */
@media (max-width:760px){.ov-views{flex-wrap:wrap;overflow-x:visible}}
.ov-hall{background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:18px 20px 20px;margin:0 0 26px}
.ov-hall-head h2{font-size:16px}.ov-hall-head p{margin:2px 0 12px;color:var(--muted);font-size:13px}
.ov-lenses{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 12px}
/* Owner 11 Nov 2026 (paused item 14): the sub-views of วิสามัญ and กิตติมศักดิ์ under the type tabs */
.ov-subviews{display:flex;flex-wrap:wrap;gap:6px;margin:-8px 0 18px}
.ov-subviews .num{font-size:12px;color:var(--muted)}
.ov-hall-body{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:28px;align-items:start}
/* Owner 23 Oct 2026: comparison bars replace the seat plan (word · bar · count · share). */.ov-legend{list-style:none;margin:0;padding:0;display:grid;gap:4px}
.ov-key{width:100%;display:grid;grid-template-columns:minmax(96px,30%) minmax(0,1fr) 52px 52px;align-items:center;gap:12px;min-height:44px;padding:6px 10px;border:1px solid transparent;border-radius:8px;background:none;cursor:pointer;text-align:left}
.ov-key:hover{background:var(--surface-2)}.ov-key[aria-pressed=true]{border-color:var(--ink);background:var(--surface-2)}
.ov-key-word{font-size:14px;line-height:1.35}.ov-bar{display:block;height:18px;border-radius:5px;background:var(--surface-2);overflow:hidden}.ov-bar i{display:block;height:100%;width:var(--w);min-width:3px;border-radius:5px;background:var(--c,#cfcfc6);transition:width .4s ease}
.ov-key strong{text-align:right}.ov-people h3{margin:0 0 8px;font-size:14px}.ov-codes{display:flex;flex-wrap:wrap;gap:6px;max-height:260px;overflow:auto;margin:0 0 12px}
.ov-person{font:inherit;font-size:12px;letter-spacing:.04em;padding:5px 8px;border:1px solid var(--line);border-left:4px solid var(--c,#cfcfc6);border-radius:6px;background:var(--surface);cursor:pointer}.ov-person:hover{background:var(--surface-2)}.ov-person[aria-pressed=true]{border-color:var(--ink);border-left-color:var(--c,#cfcfc6);background:var(--surface-2)}
@media (prefers-reduced-motion:reduce){.ov-bar i{transition:none}}
.ov-key strong{font-size:15px}.ov-key small{font-size:12px;color:var(--muted);text-align:right}
.ov-ticket-empty{margin:0;font-size:13px;color:var(--muted);padding:12px;border:1px dashed var(--line-strong);border-radius:10px}
.ov-stub{position:relative;padding:12px 16px 12px 20px;border-radius:10px;background:var(--wait-bg);color:#3d2a08;
 -webkit-mask:radial-gradient(circle at 0 50%,transparent 7px,#000 7.5px);mask:radial-gradient(circle at 0 50%,transparent 7px,#000 7.5px)}
.ov-stub::before{content:'';position:absolute;left:12px;top:8px;bottom:8px;border-left:1.5px dashed #8a520866}
.ov-stub strong{display:block;font-size:16px;letter-spacing:.06em;margin:0 0 6px}
.ov-stub dl{margin:0;display:grid;gap:2px;font-size:13px}.ov-stub dl div{display:flex;justify-content:space-between;gap:12px}.ov-stub dt{color:#6b4a14}.ov-stub dd{margin:0;font-weight:500;text-align:right}
/* Final polish P6: the button after the stub's rows is spaced like other buttons after content. */
.ov-stub .btn{margin-top:12px}
.ov-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:4px 28px}
.ov-foot{margin:8px 0 0;font-size:12px;color:var(--muted)}
.ov-pyr{display:grid;gap:4px}
.ov-pyr-head,.ov-pyr-row{display:grid;grid-template-columns:minmax(0,1fr) 78px minmax(0,1fr);align-items:center;gap:8px}
.ov-pyr-head{font-size:12px;color:var(--muted)}.ov-pyr-head span:first-child{text-align:right}.ov-pyr-head span:nth-child(2){text-align:center}
.ov-pyr-age{text-align:center;font-size:12px;color:var(--muted)}
.ov-pyr-bar{display:flex;align-items:center;gap:6px;min-height:20px}.ov-pyr-bar.f{flex-direction:row-reverse}
.ov-pyr-bar i{display:block;height:14px;width:var(--w);border-radius:3px}.ov-pyr-bar.f i{background:var(--t-events)}.ov-pyr-bar.m i{background:var(--t-identity)}
.ov-pyr-bar b{font-size:12px;font-weight:500}
.ov-rows{list-style:none;margin:0;padding:0;display:grid;gap:12px}
.ov-rows li{display:grid;grid-template-columns:110px minmax(0,1fr) 58px;align-items:center;gap:12px}
.ov-row-name{display:grid;font-size:14px}.ov-row-name small{color:var(--muted);font-size:12px}
.ov-big{font-size:20px;text-align:right}
.ov-stack{display:flex;height:14px;border-radius:7px;overflow:hidden;background:var(--surface-2)}
.ov-stack i{display:block;flex:0 0 var(--w);background:var(--c,#cfcfc6)}
.ov-dot{display:inline-block;width:10px;height:10px;border-radius:3px;background:var(--c,#cfcfc6);margin:0 5px 0 10px;vertical-align:-1px}.ov-dot:first-child{margin-left:0}
.ov-mini{list-style:none;margin:10px 0 0;padding:0;display:flex;flex-wrap:wrap;gap:6px 16px;font-size:13px}.ov-mini .ov-dot{margin-left:0}
/* Series colours: one rule set per lens, so a word such as "pending" keeps the right colour in each picture. */
[data-lens=type] [data-g=full]{--c:var(--t-review)}[data-lens=type] [data-g=associate]{--c:#b5762a}[data-lens=type] [data-g=pending-type]{--c:#8b8e88}[data-lens=type] [data-g=honorary]{--c:#c9a03c}
[data-lens=status] [data-g=approved]{--c:var(--done)}[data-lens=status] [data-g=pending]{--c:#d39a3a}[data-lens=status] [data-g=more-docs]{--c:var(--t-identity)}[data-lens=status] [data-g=rejected]{--c:var(--now)}[data-lens=status] [data-g=invited]{--c:#c9c8bd}
[data-lens=openchat] [data-g=joined]{--c:var(--t-finance)}[data-lens=openchat] [data-g=not-joined]{--c:#c0574a}[data-lens=openchat] [data-g=pending]{--c:#c9c8bd}
[data-lens=actor] [data-g=actor]{--c:var(--t-events)}[data-lens=actor] [data-g=not_actor]{--c:#7f79ad}[data-lens=actor] [data-g=pending]{--c:#c9c8bd}
[data-lens=gender] [data-g=f]{--c:var(--t-events)}[data-lens=gender] [data-g=m]{--c:var(--t-identity)}[data-lens=gender] [data-g=x]{--c:#9a9c95}
[data-lens=feeStart] [data-g="2028"]{--c:var(--t-finance)}[data-lens=feeStart] [data-g="2029"]{--c:#c9a03c}[data-lens=feeStart] [data-g="regular"]{--c:#7f79ad}[data-lens=feeStart] [data-g="none"]{--c:#c9c8bd}
[data-lens=ageBand] [data-g="0-9"]{--c:#e3e7cf}[data-lens=ageBand] [data-g="10-14"]{--c:#cbd4a6}[data-lens=ageBand] [data-g="15-19"]{--c:#b0bd7e}[data-lens=ageBand] [data-g="20-29"]{--c:#93a35c}
[data-lens=ageBand] [data-g="30-39"]{--c:#76883f}[data-lens=ageBand] [data-g="40-49"]{--c:#5b6d2c}[data-lens=ageBand] [data-g="50-59"]{--c:#42521f}[data-lens=ageBand] [data-g="60+"]{--c:#2c3a14}
@media (max-width:900px){.ov-marquee dl{grid-template-columns:repeat(2,minmax(0,1fr))}.ov-marquee dd{font-size:28px}.ov-hall{padding:14px}.ov-hall-body{grid-template-columns:1fr}.ov-key{grid-template-columns:minmax(84px,34%) minmax(0,1fr) 44px 46px;gap:8px;padding:6px 4px}.ov-rows li{grid-template-columns:92px minmax(0,1fr) minmax(52px,max-content)}}
/* Fix round 11 Nov item 157 (ก): at 320 px the overview's boxes keep inside the page; วิสามัญ › บุคลากรในวงการ scrolled sideways by 2 px (a box
   held at 300 px in a 288 px column, and a wide "100%" in its 52 px column). Was: minmax(300px,1fr) and a fixed 52px last column. */
@media (max-width:360px){.ov-grid{grid-template-columns:minmax(0,1fr)}}

/* ---------- Import existing members ---------- */
.imp-drop{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin:0 0 12px}
.imp-drop label.btn{cursor:pointer}.imp-drop label.btn:focus-within{outline:2px solid var(--focus);outline-offset:2px}
.imp-file{font-size:13px;color:var(--muted);overflow-wrap:anywhere}
.imp-how{margin:0;padding-left:20px;font-size:13px;color:var(--muted);display:grid;gap:2px}
.imp-map{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:4px 14px}
.imp-map select{width:100%}
.imp-rows{list-style:none;margin:0;padding:0;display:grid;gap:6px}
.imp-row{display:grid;grid-template-columns:54px minmax(0,1fr) auto;gap:12px;align-items:start;padding:10px 12px;background:var(--surface);border:1px solid var(--line);border-radius:8px;border-left:4px solid var(--done)}
.imp-row[data-state=review]{border-left-color:#d39a3a}.imp-row[data-state=blocked]{border-left-color:var(--now)}.imp-row[data-state=skip]{border-left-color:var(--line-strong);opacity:.75}
.imp-line{font-size:12px;color:var(--muted);padding-top:2px}
.imp-what{display:grid;gap:1px;min-width:0}.imp-what span,.imp-what small{overflow-wrap:anywhere}.imp-what small{font-size:12px;color:var(--muted)}
.imp-what .imp-fix{color:var(--t-finance)}.imp-what .imp-note{color:var(--now)}
.imp-hist-h{font-size:14px;margin:18px 0 6px}
.imp-ack{margin:0}
.imp-warn{display:grid;gap:10px;justify-items:start;margin:0 0 12px}.imp-warn p{margin:0}
/* Owner 7 Nov 2026 (fix round, FX1-01): the checked-group chooser on an import row; its name breaks between words, not anywhere. */
.imp-group{margin:6px 0 2px;max-width:320px;gap:4px}.imp-group span{overflow-wrap:normal;font-size:13px}
/* Owner 7 Nov 2026 (fix round, FX2-04): the chooser has a line of its own under the words and the state chip (registry-ui.js rowCard), so
   its placeholder and every choice read whole in each language down to 320px. Was: inside the words' column, 98px wide at 320px in
   English beside "Problem, not imported", so "— Choose —" showed as "— Choo…". */
.imp-row>.imp-group{grid-column:2/-1;margin-top:0}
@media (max-width:520px){.imp-row{grid-template-columns:minmax(0,1fr) auto}.imp-line{grid-column:1/-1}.imp-row>.imp-group{grid-column:1/-1}}
/* Owner 7 Nov 2026 (fix round, FX3-10; rule 5 "ข้อความยาว"): on a phone the state chip sits on the row's first line beside "แถว N", and the code,
   name and details take the card's whole width below, so a long chip ("Import, then look again") no longer leaves them a 95 px strip that cut
   "TOSAA-|B2N6VE" and "1999-|05-21" at 320 px. The claim rows (claim-ui.js) keep their own layout. Was: the words beside the chip. */
@media (max-width:520px){.imp-row:not(.claim-row)>.imp-line{grid-column:1;grid-row:1;align-self:center}.imp-row:not(.claim-row)>.state{grid-column:2;grid-row:1}.imp-row:not(.claim-row)>.imp-what{grid-column:1/-1;grid-row:2}.imp-row:not(.claim-row)>.imp-group{grid-row:3}}
.imp-map-box summary{cursor:pointer;min-height:44px;display:flex;align-items:center;font-size:14px;font-weight:500}
.imp-map-box[open] summary{margin-bottom:8px}
[data-lens=workRights] [data-g=thai]{--c:#c9c8bd}[data-lens=workRights] [data-g=foreign-permit]{--c:var(--t-finance)}[data-lens=workRights] [data-g=foreign-none]{--c:#c0574a}
/* QA 16 Oct 2026: touch targets of at least 44px on phones and tablets. */
@media (max-width:900px){
 .chip,.files button,.dock .tabs button,.status-seg button,.checks label,.slot-list .btn,.langs summary,.pv-seg button,.pv-bar .btn,.ov-key,.who select{min-height:44px}
 .checks label{align-items:center}
 .slot-list .btn.slot-move,.slot-list .btn.slot-remove{min-width:44px;min-height:44px}/* Q2-B-02: the bin too. Was: .slot-list .btn.slot-move{min-width:44px} */
}
/* Claim links (#/claim), owner decisions 17 Oct 2026 */
.claim-row{grid-template-columns:24px minmax(0,1fr) auto;border-left-color:var(--line-strong)}/* QA B-19 (owner 31 Oct 2026): a tick box per person and "เลือกทั้งหมด" above the list. Was: minmax(0,1fr) auto, no tick boxes */
.claim-pick{display:flex;justify-content:center;padding-top:2px}.claim-pick input,.claim-pick-all input{width:20px;height:20px;margin:0;accent-color:var(--primary);cursor:pointer}
.claim-pick-all{display:flex;align-items:center;gap:10px;min-height:44px;padding-left:18px;font-size:14px;cursor:pointer;width:max-content;max-width:100%}
.claim-row[data-claim=sent]{border-left-color:#d39a3a}.claim-row[data-claim=claimed]{border-left-color:var(--done)}.claim-row[data-claim=cannot]{opacity:.75}
.claim-actions{display:flex;flex-wrap:wrap;gap:8px;align-items:center;justify-content:flex-end}
.claim-search{max-width:320px;margin:10px 0}
/* Owner 23 Oct 2026 (owner comment 1): member list rows follow the former-member page; filters sit beside the search on wide screens. */
.member-tools{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;margin:0 0 6px}.member-tools form{flex:1 1 260px}.member-tools .claim-search{max-width:none;margin:0}
.member-filters{display:flex;flex-wrap:wrap;gap:8px}.member-filter{margin:0}
/* Fix round 11 Nov 2026 (item 218): the name of each filter, shown just above its box (out of the row, so the boxes stay level with the search box). Was: sr-only. */
.member-filter{position:relative}.member-filter-label{position:absolute;right:2px;bottom:100%;margin-bottom:2px;font-size:12px;line-height:1.3;color:var(--muted);white-space:nowrap}.member-filter:first-child .member-filter-label{right:auto;left:2px}.member-filters>.member-filter:first-child{flex:none}.member-filters>.member-filter:first-child select{max-width:none}.member-tools{padding-top:18px}.member-filter select{min-height:44px}.member-count{flex-basis:100%;margin:2px 0 0;font-size:13px;color:var(--muted)}
/* QA B-50 (owner FIX-LIST 31 Oct 2026): the search box and both filters stay on one row at every width; the filters narrow with the
   screen so the search box keeps room to read (at least 160 px at 1160–1366), and the count sits under the row.
   Was (owner 23 Oct 2026 night): one row from 901 px with filters at least 170 px wide and the count in the same row (search squeezed
   to 32–71 px), and on a phone the search above both filters. */
/* Review 1 Nov 2026 (B-50): each filter takes the width of its chosen text (no "ประเภ…" cut) and the search box gives way down to its
   floor (160 px from 601 px, 100 px on a phone). Was (this round): filters fixed at clamp(92px,11vw,170px), and on a phone
   calc(25vw + 4px) up to 124 px, which cut "ประเภท · ทั้งหมด" and "ไม่ใช่นักแสดง" mid-word while the search box had room to spare.
   On a phone the padding beside the arrow is trimmed so "ไม่ใช่นักแสดง" fits at 320–390. The max-width caps keep browsers without
   field-sizing (width = longest choice) on one row. Was known limit: at 320 px the longest choice "นักแสดงเด็ก / เยาวชน" shortened; from 1 Nov 2026 a phone shows "เด็ก / เยาวชน" (registry-ui.js). */
.member-tools{display:grid;grid-template-columns:minmax(160px,1fr) auto;align-items:center;gap:10px 8px}
.member-tools form{min-width:0}.member-filters{flex-wrap:nowrap}.member-count{grid-column:1/-1}
.member-filter select{width:auto;field-sizing:content;max-width:180px;min-width:0;text-overflow:ellipsis}
/* Owner 7 Nov 2026 (fix round, FX1-03; rule of 19 Oct and B-50 "ลดความกว้างตัวกรองได้ ... ไม่ย้ายลงบรรทัดใหม่"): on a phone the search box gives
   way down to 64 px, so both filters keep their whole chosen text when the sub-filter shows (กิตติมศักดิ์ + ไม่ใช่นักแสดง, Associate + Child /
   Youth at 320–360 px); the search hint (ค้นหา / Search / 搜索, registry-ui.js) fits what is left, its clear button's room included. Was:
   minmax(100px,1fr), which squeezed the filters to "กิตติม…" / "ไม่ใช่นักแ…" at 320 px. */
@media (max-width:600px){.member-tools{grid-template-columns:minmax(78px,1fr) auto/* item 218: room for the hint "Search" beside the full group names. Was: minmax(64px,1fr) */}.member-filter select{max-width:min(170px,calc(100vw - 205px));font-size:14px;padding-left:8px;padding-right:6px}.member-tools .claim-search input{padding-left:9px;padding-right:6px}}
@media (max-width:360px){.member-filter select{font-size:13px;padding-left:6px;padding-right:3px}
 /* Next chat (ข10): "General public" (English, was "Public") is wider, so at 320 px the row takes a little less gap and side padding to keep the
    search hint whole on the same row. Was: gap 8px, search padding 9px/6px. */
 .member-filters{gap:5px}.member-filter select{padding-left:4px;padding-right:1px}.member-tools .claim-search input{padding-left:6px;padding-right:2px}}
.member-row .what{color:inherit;text-decoration:none}.member-row .what:hover strong{text-decoration:underline}.member-tags{display:flex;flex-wrap:wrap;gap:6px}
.member-tags .tag{background:var(--surface-2);color:var(--ink)}.member-tags .tag.warn{background:var(--wait-bg)}
.claim-search input{width:100%;min-height:44px;border:1px solid var(--line-strong);border-radius:8px;background:#fff;padding:9px 11px;font:inherit}
.claim-mail{position:fixed;inset:0;z-index:60;background:#0008;display:grid;place-items:center;padding:16px}
.claim-mail-card{background:var(--surface);color:var(--ink);border:1px solid var(--line);border-radius:12px;width:min(640px,100%);max-height:calc(100dvh - 32px);overflow:auto;padding:20px}
.claim-mail-top{display:flex;justify-content:space-between;align-items:center;gap:12px}
.claim-mail-top h2{margin:0;font-size:18px}
.claim-mail-meta{display:grid;grid-template-columns:auto 1fr;gap:4px 12px;margin:14px 0;font-size:14px}
.claim-mail-meta dt{color:var(--muted)}.claim-mail-meta dd{margin:0}
.claim-mail-body{white-space:normal;border-top:1px solid var(--line);padding-top:12px}
.claim-frame{width:100%;height:620px;border:1px solid var(--line);border-radius:10px;background:#191919;margin-top:8px}
@media(max-width:640px){.claim-row{grid-template-columns:24px minmax(0,1fr)}/* B-19. Was: 1fr */.claim-actions{grid-column:2;justify-content:flex-start}}
/* Document viewer, owner request 17 Oct 2026 */
.file-viewer{width:min(900px,calc(100% - 24px));max-height:calc(100dvh - 24px);padding:0;border:1px solid var(--line);border-radius:12px;background:var(--surface);color:var(--ink)}
.file-viewer::backdrop{background:#000a}
.fv-top{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;padding:14px 16px;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--surface)}
.fv-top h2{margin:0;font-size:17px}.fv-top small{color:var(--muted)}
.fv-body{padding:12px;display:grid;place-items:center;background:#2b2a27}
.fv-img{max-width:100%;max-height:70dvh;object-fit:contain;background:#fff}
.fv-pdf{width:100%;height:70dvh;border:0;background:#fff}
.fv-log{margin:0;padding:10px 16px;font-size:12px;color:var(--muted);border-top:1px solid var(--line)}
.draft-note{margin:8px 0 0;font-size:13px;color:var(--muted)}
/* New-features block X2: the FAQ editor (governance-ui.js EXT.pages.faq). The set switch is the dock’s tab control; rows, inline
   forms and buttons are the settings pages’ own. */
.gov-faq-sets{display:inline-flex;margin:0 0 18px}
.gov-faq-sets button{padding:0 16px;font:inherit;font-size:13px;white-space:nowrap}
.gov-faq-cat-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px 14px;margin-bottom:6px}
.gov-faq-cat-head h2{margin:0}
.gov-faq-add{margin:0 0 26px}
.gov-faq-cat .gov-faq-add{margin:12px 0 0}
.gov-faq-move{min-width:44px;padding:8px}
.gov-faq-move.down svg{transform:rotate(180deg)}
.gov-item .what .gov-faq-missing{color:var(--wait)}
.gov-faq-changes{margin:4px 0 14px;font-size:14px}
.gov-faq-changes ul{margin:6px 0 0;padding-left:1.2em;display:grid;gap:4px;font-size:13px;color:var(--muted)}
/* Final polish Part 1, text wrap (owner 19 Oct 2026, "ไม่ชอบคำตกลงมาไม่สวย ไม่ว่าจะภาษาไหน"; plan TEXT-WRAP-SWEEP): the same shared rule as
   shared-navigation/header.css, for a page that does not load it. Headings, titles and short labels wrap balanced (no lone word or short
   fragment on the last line), paragraphs avoid a short last line; :where() keeps it at zero specificity. */
:where(h1,h2,h3,h4,h5,h6,legend,summary,button,[role="tab"],[role="button"],th,dt,figcaption,label,strong,b,.btn,[class*="title"],[class*="heading"],[class*="label"],[class*="fee"],[class*="price"],[class*="chip"],[class*="badge"],[class*="status"],[class*="caption"],#footer>span){text-wrap:balance}
:where(p,li,dd,td,blockquote){text-wrap:pretty}
.tosaa-term{white-space:nowrap}
/* Owner 26 Oct 2026: one box per duty name, so a long name wraps between its words inside the menu line. */
.duty-words{min-width:0;flex:0 1 auto}
.row>.time,.gov-acct .what>small{text-wrap:balance}/* final polish Part 1: "Waiting 53 min" and a staff account line left "min" / "备 1" alone on the last line */
.gov-acct .what .gov-acct-state{white-space:nowrap}/* QA B-18: "ใช้งาน · อุปกรณ์ที่เข้าระบบ 1" stays one line; the email has its own line */
.gov-acct .what .gov-acct-duty{display:inline-block;max-width:100%;vertical-align:top}/* Owner 7 Nov 2026 (fix round, B-18): one duty with its " ·" is one unit (governance-ui.js dutyLine), as .td-creator-role; it wraps inside itself only when wider than the line. Was: one plain line of duties */
.gov-acct .what>small[data-gov-acct-duties]{text-wrap:wrap}/* B-18: duties fill each line in order; balancing left one duty alone between two lines ("Reports ·" at 390 px). Was: balance, as the other small lines */
/* Model documents (owner 22 Oct 2026): three featured slots in the order picked, each document's versions folded under it. */
.gov-contract-sub{margin:0 0 10px;font-size:13px;color:var(--muted)}
.gov-contract-slots{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;margin:0 0 6px;padding:0;list-style:none}
.gov-contract-slots li{display:grid;align-content:start;gap:4px;min-height:76px;padding:10px;border:1px solid var(--line);border-radius:8px;background:var(--surface);font-size:13px;overflow-wrap:anywhere}
/* QA B-03 (owner 31 Oct 2026, "ใช้การเลื่อนแนวนอน"): the three recommended cards keep a readable width and the row scrolls sideways when
   the column is too narrow for three; a title breaks only between words, with balanced lines. Was: three columns at any width, so at
   320px a card was 92px and titles were cut mid-word ("employ|ment"). */
.gov-contract-slots{grid-template-columns:none;grid-auto-flow:column;grid-auto-columns:minmax(180px,1fr);overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x proximity;padding-bottom:4px}
.gov-contract-slots li{overflow-wrap:normal;scroll-snap-align:start}.gov-contract-slots li>span:last-child{text-wrap:balance}
/* QA B-03 review (1 Nov 2026): with a mouse the sideways row shows a thin scroll bar, so every card can be reached also where the side
   panel narrows the column (901–1279px). The class beats the page-wide "no scroll bar" rule below (html,body,*). Was: no visible bar. */
@media (pointer:fine){.gov-contract-slots{scrollbar-width:thin;scrollbar-color:var(--line-strong) transparent}
 .gov-contract-slots::-webkit-scrollbar{display:block;height:8px}.gov-contract-slots::-webkit-scrollbar-thumb{background:var(--line-strong);border-radius:4px}}
.gov-contract-slots li.empty{border-style:dashed;color:var(--muted)}
.gov-contract-slots .num{font-size:18px;font-weight:600;line-height:1;color:#80602a}
.gov-contract-doc>.gov-contract-versions{flex:1 1 100%;margin:2px 0 0}
.gov-contract-doc>.gov-contract-versions>summary{cursor:pointer;font-size:13px;color:var(--muted);min-height:32px;display:flex;align-items:center}
.gov-contract-versions .gov-item{padding-left:12px;border-left:2px solid var(--line)}
.gov-contract-doc .gov-contract-rank{color:#80602a!important;font-weight:500}
.gov-contract-doc [data-gov-contract-feature][aria-pressed=true]{background:#80602a;border-color:#80602a;color:#fff}
.gov-contract-langs{margin:0 0 12px}.gov-contract-langs>summary{cursor:pointer;font-size:13px;color:var(--muted);min-height:36px;display:flex;align-items:center}
.gov-contract-pair{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,8em);align-items:end;gap:10px}
.gov-contract-pair input[type=number]{width:100%;min-height:44px;border:1px solid var(--line-strong);border-radius:8px;background:#fff;padding:9px 11px;font:inherit}
/* Owner 23 Oct 2026 night: คิว shows one large tile per duty. */.queue-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px;margin:8px 0 24px}.queue-tile{display:grid;align-content:start;gap:8px;min-height:120px;padding:16px;border:1px solid var(--line);border-radius:14px;background:var(--surface);color:inherit;text-decoration:none}.queue-tile:hover{border-color:var(--ink)}.queue-tile strong{font-size:16px}.queue-tile small{color:var(--muted);font-size:13px}.queue-tile .state{justify-self:start}
@media (max-width:520px){.queue-tiles{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* Owner 25 Oct 2026 (comments 6 and 9): หน้าหลัก's destinations as icon buttons, like the member app's Home (.tosaa-home-actions): a coloured
   square in the duty colours (.tone-*) with the name under it; 4 across, 3 on a phone. */
.staff-tiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:24px 16px;max-width:560px;padding:6px 0 4px}
.staff-tile{display:flex;flex-direction:column;align-items:center;gap:8px;min-width:0;text-align:center;text-decoration:none;color:var(--ink)}
.staff-tile>span{display:grid;place-items:center;width:56px;height:56px;border-radius:18px;transition:filter .16s ease}
.staff-tile>span svg.i{width:24px;height:24px}
.staff-tile strong{font-size:12px;font-weight:400;line-height:1.6;overflow-wrap:anywhere}
.staff-tile:hover>span{filter:brightness(.94)}
.staff-tile:focus-visible{outline-offset:4px}
@media (max-width:600px){.staff-tiles{grid-template-columns:repeat(3,minmax(0,1fr));gap:22px 12px}}
/* Owner 25 Oct 2026 (comment 11): a duty's queue has a status control with counts above the list (look of the dock's tabs); วันนี้ ends
   with the way to the rest of the work. */
.status-seg{flex-wrap:wrap;margin:0 0 22px}
.status-seg button{flex:1 1 auto;padding:4px 12px}
.status-seg .num{color:var(--muted);margin-left:2px}
.today-more{margin:-8px 0 24px;font-size:14px}
/* Owner 25 Oct 2026: งาน's sections (เข้ามาใหม่ · ค้าง · ครบกำหนดวันนี้ · ทั้งหมด) as one segmented row of links that wraps on a phone;
   the duty switch on a queue; บัญชีของฉัน's list of duties. */
.work-sections{display:flex;flex-wrap:wrap;gap:4px;padding:3px;margin:0 0 22px;background:var(--surface-2);border-radius:9px}
.work-sections a{flex:1 1 auto;display:inline-flex;align-items:center;justify-content:center;gap:4px;min-height:44px;padding:4px 12px;border-radius:7px;font-size:13px;color:inherit;text-decoration:none;white-space:nowrap}
.work-sections a[aria-current=page]{background:var(--surface);box-shadow:0 1px 3px #0000001a;font-weight:500}
.work-sections .num{color:var(--muted)}
/* Owner 26 Oct 2026: tabs for the kinds of work inside a merged duty, kept apart (เรื่องร้องเรียน · ปัญหาแอปและบัญชี · เคสลงพื้นที่). */
a.chip{color:inherit;text-decoration:none;min-height:44px}
a.chip[aria-current=page]{background:var(--ink);border-color:var(--ink);color:#fff}
a.chip[aria-current=page] .num{color:#fff}
.account-duties{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.account-duties li{display:flex;align-items:center;gap:8px;font-size:14px}
.account-duties .dot{width:10px;height:10px;border-radius:3px;flex:none}
@media (max-width:520px){.work-sections{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}.work-sections a{white-space:normal;text-align:center}}
/* Owner 25–26 Oct 2026: การเงินสมาคม is one list. Above it a toolbar (เพิ่มรายการเอง · นำเข้าไฟล์รายการเดินบัญชี · กฎที่จำไว้) whose panels
   float over the page and never push it down (owner rule for every dropdown), anchored to the toolbar so they fit a phone; the filter
   ทั้งหมด / รอจัดหมวด (look of the status control); below it the month-end check; in an item's dock the same floating panels for "จำกฎ"
   and "ไม่ใช่รายการของสมาคม / ซ้ำ". The bank's description is for staff only. */
.ledger-tools{margin:0 0 14px}
.ledger-tools-row,.dock-pops{position:relative;display:flex;flex-wrap:wrap;gap:8px}
.ledger-tools-row>.btn,.pop>summary{min-height:44px}
.ledger-tools .hint-line{margin:8px 0 0;overflow-wrap:anywhere}
.pop{position:static}
.pop>summary{list-style:none;cursor:pointer}
.pop>summary::-webkit-details-marker{display:none}
.pop>summary .num{color:var(--muted)}
.pop[open]>summary{background:var(--surface-2)}
.pop-panel{position:absolute;z-index:20;top:calc(100% + 6px);left:0;width:min(420px,100%);max-height:70vh;overflow:auto;display:grid;gap:12px;padding:16px;background:var(--surface);border:1px solid var(--line);border-radius:12px;box-shadow:0 14px 34px #1d212429}
.dock-pops .pop-panel{width:100%}
.dock-pops.up .pop-panel{top:auto;bottom:calc(100% + 6px)}/* QA S-24: opens upward when there is no room below */
.ledger-kind{display:grid;gap:12px}.ledger-identify-title{margin:0;font-size:16px;font-weight:600}/* QA S-24: the "ระบุรายการ" step */
/* Owner 7 Nov 2026 (fix round, N-07): the lock box at the top of a published item's dock (set apart from the forms that correct it), the
   "ยอดตามหลักฐาน" form, and a month's lock line on the list. */
.ledger-lock{display:grid;gap:12px;padding-bottom:16px;border-bottom:1px solid var(--line)}
.dock form.ledger-proof{gap:10px}.ledger-proof .result,.ledger-proof .hint-line{margin:0}
.ledger-month-lock{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px;margin:0 0 10px}.ledger-month-lock .hint-line{margin:0}
.ledger-month-lock .btn{min-height:44px}
.pop-panel form{display:grid;gap:12px}
.pop-panel .rows{margin:0}
.ledger-filter{margin:0 0 18px}
.ledger-filter button{min-height:44px}
.ledger-below{margin-top:8px}
.gov-item .what small.bank-desc,.bank-desc{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:var(--muted);overflow-wrap:anywhere}
.bank-monthend .result,.bank-monthend .notice{margin:12px 0 0}
.bank-monthend .notice p{margin:0 0 6px}
.bank-unsorted{margin:0;padding-left:20px;font-size:14px}
.bank-unsorted a{color:inherit}
/* Owner 26 Oct 2026: no scroll bar at the screen's right edge (บัญชีของฉัน, สมาชิก and every page); the page still scrolls.
   Same rule as the member app (shared-navigation/navigation.css). */
html,body,*{scrollbar-width:none}
*::-webkit-scrollbar{display:none;width:0;height:0}
/* Owner 26 Oct 2026: report shortlist and folders. */
.rep-strip{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 18px}
.rep-strip .rep-case{margin-left:auto;background:var(--t-finance-bg);border-color:transparent;color:var(--t-finance);font-weight:500}
.rep-strip a,.rep-chip a{display:inline-flex;align-items:center;gap:6px;min-height:40px;padding:4px 14px;border:1px solid var(--line);border-radius:999px;background:var(--surface);color:var(--ink);font-size:14px;text-decoration:none;white-space:nowrap}
.rep-strip svg.i,.rep-chip svg.i,.rep-star svg.i,.rep-folders svg.i{width:18px;height:18px}
.rep-tools{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-bottom:12px}
.rep-star{display:inline-flex;align-items:center;gap:6px}
.rep-star.on{background:var(--t-quests-bg);border-color:var(--t-quests);color:var(--t-quests)}
.rep-star.on svg.i{fill:currentColor}
.rep-chip{display:inline-flex;align-items:center;gap:2px;border-radius:999px;background:var(--t-cases-bg)}
.rep-chip a{border-color:transparent;background:transparent;color:var(--t-cases)}
.rep-chip button{min-width:36px;min-height:40px;border:0;background:transparent;color:var(--t-cases);font-size:18px;cursor:pointer}
.rep-file{display:flex;flex-wrap:wrap;align-items:end;gap:10px;margin:4px 0 0}
.rep-file .field{flex:1 1 200px;margin:0}
.rep-file:has(select option[value=new]:checked) [data-rep-new-name],.rep-file:not(:has(select)) .field{display:block}
.rep-file:has(select):not(:has(option[value=new]:checked)) [data-rep-new-name]{display:none}
.rep-similar{list-style:none;margin:0;padding:0}
.rep-similar li a{display:block;padding:10px 4px;border-bottom:1px solid var(--line);color:inherit;text-decoration:none}
.rep-similar li a:hover strong{text-decoration:underline}
.rep-similar strong{display:block;font-weight:500}
.rep-similar small{display:block;font-size:13px;color:var(--muted)}
.rep-folders{list-style:none;margin:16px 0 0;padding:0;display:grid;gap:8px}
.rep-folders a{display:flex;align-items:center;gap:12px;padding:12px 14px;border:1px solid var(--line);border-radius:14px;background:var(--surface);color:var(--ink);text-decoration:none}
.rep-folders a>svg.i{flex:none;color:var(--t-cases)}
.rep-folders strong{display:block;font-weight:500}
.rep-folders small{display:block;font-size:13px;color:var(--muted)}
/* Owner 28 Oct 2026: งาน → a duty's page of features → its work. */
.feature-tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:12px;margin:8px 0 24px}
.feature-tiles.compact{grid-template-columns:repeat(auto-fill,minmax(200px,1fr));margin:0}
.feature-tile{position:relative;display:flex;align-items:center;gap:14px;min-height:84px;padding:14px 16px;border:1px solid var(--line);border-radius:16px;background:var(--surface);color:var(--ink);text-decoration:none}
.feature-tile:hover{border-color:var(--line-strong)}
.feature-tile>span:first-child{display:grid;place-items:center;flex:none;width:48px;height:48px;border-radius:14px}
.feature-tile>span:first-child svg.i{width:24px;height:24px}
.feature-tile .ft-text{min-width:0}
.feature-tile strong{display:block;font-size:16px;font-weight:600}
.feature-tile small{display:block;font-size:13px;color:var(--muted);line-height:1.5;text-wrap:balance}/* QA B-04 (owner 31 Oct 2026): balanced lines, no word left alone on the last line. Was: no text-wrap */
.feature-tile .count{position:absolute;top:10px;right:12px;min-width:24px;padding:0 8px;border-radius:999px;background:var(--t-quests-bg);color:var(--t-quests);font-size:13px;text-align:center}
/* Owner 7 Nov 2026 (fix round, Q2-B-26, placed as the owner's Q2-B-15 note for the duty tiles): the count still sits at the top right, on
   the tile's corner over its border, so a long name ("Confirm and give points", "Review applications", "รายการเงินที่ต้องตรวจ") is never
   under it and keeps its whole row; a ring of the page colour keeps it apart from the border. Was: top:10px;right:12px, inside the tile, on
   top of the end of the name. */
.feature-tile .count{top:-9px;right:-8px;min-width:24px;padding:2px 8px;line-height:16px;box-shadow:0 0 0 2px var(--ground)}
@media (max-width:520px){.feature-tiles{grid-template-columns:1fr}}
/* Owner 28 Oct 2026: the reports tools stay on one row on a phone too. */
@media (max-width:520px){nav.rep-strip{flex-wrap:nowrap;gap:6px}nav.rep-strip a{flex:0 1 auto;min-width:0;padding:4px 10px;font-size:13px;gap:4px}nav.rep-strip svg.i{width:16px;height:16px;flex:none}nav.rep-strip .rep-case{margin-left:0}
 /* QA B-08 (owner 31 Oct 2026): ติดดาว · โฟลเดอร์ · เปิดเคสลงพื้นที่ keep their full words, spacing and icons; on a narrow phone the three
    share one smaller font size, worked out from the screen width so the row fits (100vw - page padding 32 - gaps 12 - padding, border,
    icon and icon gap 3 × 42 = 100vw - 170px of text; the factor per language is 1 / its text width per px of font, less 2%). Was: 13px,
    so in English at 320px the row ran 32px past the screen and the counts were cut. */
 nav.rep-strip:has(.rep-case) a{font-size:clamp(8px,calc((100vw - 170px) * .069),13px)}
 html[lang=en] nav.rep-strip:has(.rep-case) a{font-size:clamp(8px,calc((100vw - 170px) * .058),13px)}
 html[lang|=zh] nav.rep-strip:has(.rep-case) a{font-size:clamp(8px,calc((100vw - 170px) * .071),13px)}}
/* Owner 28 Oct 2026 (later): งาน's งานด่วน as three small cards and the duties as compact tiles with an icon in the duty colour.
   Was: a row of pills, and tall cards with a dot. */
.queue-tiles.duty-tiles{grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:10px}
.queue-tile.duty-tile{display:flex;align-items:center;gap:12px;min-height:72px;padding:12px 14px;border-radius:16px}
.duty-tile .dt-icon{display:grid;place-items:center;flex:none;width:44px;height:44px;border-radius:13px}
.duty-tile .dt-icon svg.i{width:22px;height:22px}
.duty-tile .dt-text{flex:1;min-width:0}
.duty-tile .dt-text strong{display:block;font-size:15px;font-weight:600;line-height:1.35}
.duty-tile .dt-text small{display:block;margin-top:2px;font-size:13px;color:var(--muted)}
.duty-tile .dt-count{flex:none;min-width:28px;padding:2px 9px;border-radius:999px;background:var(--t-cases-bg);color:var(--t-cases);font-size:13px;font-weight:600;text-align:center}
/* Owner 7 Nov 2026 (fix round, Q2-B-15: "เอาไปอยู่มุมขวาบนของ box หมวดนั้นๆแทนเลย จะได้ไม่ต้องแก้ตรง text หัวข้อหมวด"): the count of work waiting
   sits on the top right corner of the duty's tile, over its border, so the duty's name keeps the whole row and is never under it
   ("News/events/quests", "申请、身份与账户恢复"); its words are unchanged. Was: at the end of the row beside the name (flex:none). */
.queue-tile.duty-tile{position:relative}
.duty-tile .dt-count{position:absolute;top:-9px;right:-8px;min-width:26px;padding:2px 8px;line-height:16px;box-shadow:0 0 0 2px var(--ground)}
@media (max-width:520px){.queue-tiles.duty-tiles{grid-template-columns:1fr}}
/* Owner 28 Oct 2026 (latest): เขียนประกาศ is one page with tabs ข่าว · กิจกรรม · ภารกิจ; each tab has a small + create button beside its
   heading. Was: tinted create buttons in a row above a tile per kind. */
.tone-text-content{--tone:var(--t-content);--tone-bg:var(--t-content-bg)}.tone-text-events{--tone:var(--t-events);--tone-bg:var(--t-events-bg)}.tone-text-quests{--tone:var(--t-quests);--tone-bg:var(--t-quests-bg)}.tone-text-finance{--tone:var(--t-finance);--tone-bg:var(--t-finance-bg)}
.post-tabs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px;max-width:520px;margin:4px 0 20px;padding:4px;border-radius:14px;background:var(--surface-2)}
.post-tabs a{display:flex;align-items:center;justify-content:center;gap:6px;min-height:44px;padding:6px 8px;border-radius:10px;color:var(--muted);font-size:14px;text-decoration:none;white-space:nowrap}
.post-tabs a svg.i{width:18px;height:18px}
.post-tabs a .num{font-size:12px;opacity:.8}
.post-tabs a:hover{color:var(--ink)}
.post-tabs a[aria-current=page]{background:var(--surface);color:var(--tone);font-weight:600;box-shadow:0 1px 2px rgba(0,0,0,.06)}
.post-tab-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:0 0 18px}
.post-tab-head p{margin:0;font-size:14px;color:var(--muted)}
.post-new{display:inline-flex;align-items:center;gap:6px;min-height:40px;padding:4px 14px 4px 10px;border-radius:999px;background:var(--tone-bg);color:var(--tone);font-size:14px;font-weight:600;text-decoration:none;white-space:nowrap}
.post-new svg.i{width:18px;height:18px;stroke-width:2.2}
.post-new:hover{box-shadow:inset 0 0 0 1px var(--tone)}
@media (max-width:520px){.post-tabs{max-width:none}}
/* Owner 28 Oct 2026: the member list and the overview switch with one long button each. */
.member-switch{display:flex;align-items:center;gap:10px;width:100%;max-width:560px;min-height:52px;margin:0 0 18px;padding:8px 14px;border:1px solid var(--line);border-radius:14px;background:var(--surface);color:var(--ink);font-size:15px;font-weight:600;text-decoration:none}
.member-switch>svg.i:first-child{width:22px;height:22px;padding:6px;box-sizing:content-box;border-radius:10px;background:var(--t-review-bg);color:var(--t-review)}
.member-switch[data-member-switch=overview]>svg.i:first-child{background:var(--t-finance-bg);color:var(--t-finance)}
.member-switch span{flex:1}
.member-switch>svg.i:last-child{width:18px;height:18px;transform:rotate(180deg);color:var(--muted)}
.member-switch:hover{border-color:var(--line-strong)}
/* Owner 28 Oct 2026 (approved proposal): รับรองและให้แต้ม, a folder per event and quest; each folder has รอตรวจ · ตรวจแล้ว and, for an
   event, its own QR scan button. */
.pt-folders{list-style:none;margin:6px 0 24px;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:10px}
.pt-folder,.pt-scan{display:flex;align-items:center;gap:12px;min-height:72px;padding:12px 14px;border:1px solid var(--line);border-radius:16px;background:var(--surface);color:var(--ink);text-decoration:none}
.pt-folder:hover,.pt-scan:hover{border-color:var(--line-strong)}
.pt-icon{display:grid;place-items:center;flex:none;width:44px;height:44px;border-radius:13px}
.pt-icon svg.i{width:22px;height:22px}
.pt-text{flex:1;min-width:0}
.pt-text strong{display:block;font-size:15px;font-weight:600;line-height:1.35}
.pt-text small{display:block;margin-top:2px;font-size:13px;color:var(--muted);line-height:1.45}
.pt-pts{white-space:nowrap}/* Fix-round B-09: "21 พ.ย." and "60 แต้ม/คน" each stay one piece. */
.pt-badge{flex:none;padding:3px 10px;border-radius:999px;background:var(--t-cases-bg);color:var(--t-cases);font-size:13px;font-weight:600;white-space:nowrap}
.pt-clear{flex:none;font-size:13px;color:var(--muted);white-space:nowrap}
.pt-scan{max-width:560px;margin:0 0 8px;border-color:transparent;background:var(--t-events-bg)}
.pt-scan .pt-icon{background:var(--surface)}
.pt-scan>svg.i:last-child{width:18px;height:18px;transform:rotate(180deg);color:var(--t-events)}
.pt-tabs{grid-template-columns:repeat(2,minmax(0,1fr));max-width:420px;margin-top:14px}
.pt-tabs a[aria-current=page]{color:var(--ink)}
.pt-rows .pt-row{display:flex;align-items:center;gap:12px;padding:12px 4px;color:var(--ink);text-decoration:none}
.pt-rows li{border-bottom:1px solid var(--line)}
.pt-rows .pt-row .what{flex:1;min-width:0}
.pt-rows .pt-row .what strong{display:block;font-weight:600}
.pt-rows .pt-row .what small{display:block;font-size:13px;color:var(--muted)}
.pt-rows .pt-row .btn{flex:none;white-space:nowrap}
.pt-rows .pt-row .state{flex:none}
@media (max-width:520px){.pt-folders{grid-template-columns:1fr}}
/* Fix-round B-09 (owner 31 Oct: "พยายามให้อยู่บรรทัดเดียว"): the รอตรวจ / ตรวจครบแล้ว badge sits under the title, so the line
   "ภารกิจ · 21 พ.ย. · 60 แต้ม/คน" keeps the card's width and stays on one line (phone and the 300px desktop cards). Was: the badge
   took the right side and the line wrapped. */
.pt-folder{display:grid;grid-template-columns:44px minmax(0,1fr);column-gap:12px;row-gap:6px}
.pt-folder>.pt-icon{grid-row:span 2;align-self:center}
.pt-folder>.pt-badge,.pt-folder>.pt-clear{grid-column:2;justify-self:start}
/* Owner 28 Oct 2026 (latest): งานด่วน sits under the duties as one tab row with icons and its list. */
.urgent-sec{margin-top:8px}
.urgent-head{margin:0 0 10px}
.urgent-head h2{margin:0;font-size:17px;font-weight:600}
.urgent-head p{margin:2px 0 0;font-size:13px;color:var(--muted)}
.work-sections a svg.i{width:16px;height:16px;flex:none}
.work-sections a{gap:6px}
/* Owner 28 Oct 2026 (latest, "มือถือแนวตั้ง … ให้เป็นแถวเดียวให้ได้"): on a portrait phone the four tabs share one row; each tab puts its
   count under its word in a smaller size. Was: the tabs wrapped to two rows. Other sizes keep one row already. */
@media (max-width:520px) and (orientation:portrait){
 .work-sections{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:2px;padding:3px}
 .work-sections a{flex-direction:column;justify-content:center;gap:0;min-height:52px;padding:4px 2px;font-size:12px;line-height:1.3;white-space:nowrap}
 .work-sections a svg.i{display:none}
 .work-sections a .num{font-size:12px}
}
@media (max-width:350px) and (orientation:portrait){.work-sections a,.work-sections a .num{font-size:11px;letter-spacing:-.1px}}
/* Fix-round B-42: on a phone every การเงินสมาคม row reads "date · category" then the amount on a line of its own, so amounts line up
   and no line ends with "·". Was: the amount followed on the same text and dropped alone to a second line on some rows only. */
@media (max-width:520px){.gov-item .what small .ledger-amt{display:block}.gov-item .what small .ledger-sep{display:none}}
/* Owner 29 Oct 2026 (portrait phone, "ให้เป็นแถวเดียว"): การเงินสมาคม's three tools share one row, an icon over a short word; the status
   filter of a work list keeps one row with the count under each word. Was: each tool on its own row; the filter wrapped. */
@media (max-width:520px) and (orientation:portrait){
 .ledger-tools-row{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:6px}
 .ledger-tools-row>.btn,.ledger-tools-row>.pop>summary{width:100%;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;min-height:64px;padding:8px 4px;font-size:12.5px;line-height:1.25;text-align:center;white-space:nowrap}
 .ledger-tools-row svg.i{width:20px;height:20px}
 .ledger-tools-row>.pop{display:block;min-width:0}
 /* Fix-round B-02: six or seven statuses are wider than a 320-390px phone; the row scrolls sideways inside itself and the page
    never does. Was: the last button ran past the screen edge and the whole page could be dragged sideways. */
 .status-seg{flex-wrap:nowrap;gap:2px;max-width:100%;overflow-x:auto;overscroll-behavior-x:contain;scrollbar-width:none}
 .status-seg::-webkit-scrollbar{display:none}
 .status-seg button{flex:1 0 auto;display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:52px;padding:4px 5px;font-size:12px;line-height:1.3;white-space:nowrap}
 .status-seg .num{margin-left:0}
}
@media (max-width:350px) and (orientation:portrait){.status-seg button,.ledger-tools-row>.btn,.ledger-tools-row>.pop>summary{font-size:11px}}
/* Owner 29 Oct 2026: the chevron back and the page heading share one row; the chevron sits close to the left edge, never off screen. */
.title-row{display:flex;align-items:flex-start;gap:2px;margin-left:-12px}
.title-row>a.back-icon{flex:none;width:40px;height:40px;min-height:40px;margin:0;padding:0;justify-content:center;border-radius:10px}
.title-row>a.back-icon svg.i{width:22px;height:22px}
.title-row>h1{flex:1;min-width:0;padding-top:1px}
.sheet-head .title-row>h1{font-size:24px;line-height:38px}
.item-head .title-row>h1{font-size:24px;line-height:38px}/* item 140: the size of the other page titles. Was: 22px */
@media (max-width:640px){.title-row{margin-left:-14px}.sheet-head .title-row>h1,.item-head .title-row>h1{font-size:20px;line-height:1.35;padding-top:6px}}

/* Owner 7 Nov 2026 (fix round, VOTE-13, VOTE-14, VOTE-15; VOTING-SPEC-TH.md 4.5, 5.4, 5.7, 15): the votes duty (votes-ui.js). The three choice
   colours are small marks only, always with the choice's own icon and word (a tick, a cross, a dash), so colour is never the only sign; the
   red of "ไม่เห็นด้วย" is not the state red kept for errors. Result bars and tables stay ink on paper. Values are the spec's staff column. */
:root{--vote-agree:#246e3a;--vote-disagree:#993a33;--vote-abstain:#5f5d5a}
.vote-mark{display:inline-grid;place-items:center;flex:none;width:26px;height:26px;border-radius:50%;border:1.5px solid currentColor;background:var(--surface)}
.vote-mark svg.i{width:15px;height:15px;stroke-width:2.4}
.vote-mark[data-option=agree]{color:var(--vote-agree)}.vote-mark[data-option=disagree]{color:var(--vote-disagree)}.vote-mark[data-option=abstain]{color:var(--vote-abstain)}
.vote-no{display:inline-grid;place-items:center;flex:none;min-width:26px;height:26px;padding:0 6px;border-radius:13px;border:1.5px solid var(--ink);background:var(--surface);color:var(--ink);font-size:13px;font-weight:600}
/* Owner 7 Nov 2026 (fix round, VOTE-16): the list's band heads keep their heading and count on one line each; on a phone the waiting hint goes
   under them instead of squeezing them ("รอคน / อื่น", "2 / รายการ"). */
[data-vote-band] .band-head{flex-wrap:wrap;row-gap:2px}
[data-vote-band] .band-head :is(h2,.n){white-space:nowrap}
.vote-opts{list-style:none;margin:0;padding:0;display:grid;gap:8px}
.vote-opts li{display:flex;align-items:center;gap:10px;min-height:46px;padding:8px 12px;border:1px solid var(--line);border-radius:9px;background:var(--surface);font-weight:500}
/* Next chat (จ29, R-V2-N1): the choices fill a row only while each has room for its name (the vote page's left column near 925 px read
   "งดออก / เสียง" in a 30 px box); narrower, they stack. Was: repeat(3,minmax(0,1fr)) from 600 px. */
@media (min-width:600px){.vote-opts{grid-template-columns:repeat(auto-fit,minmax(10.5em,1fr))}}
.vote-kinds label>span{display:grid;gap:0}
.vote-kinds label strong{font-weight:500}
.vote-kinds label small{font-size:12px;color:var(--muted)}
.vote-form-lock{border:0;margin:0;padding:0;min-width:0}
/* Fix round 11 Nov 2026 item 128: a cancel reason with a long unbroken word (a file name) wraps inside its box. Was: it pushed the page wider. */
[data-vote-cancelled],[data-vote-cancel-pending]{overflow-wrap:anywhere}
.vote-cands{list-style:none;margin:0;padding:0;display:grid;gap:14px}
.vote-cand{display:grid;gap:12px;padding:14px;border:1px solid var(--line);border-radius:12px;background:var(--surface-2)}
.vote-cand-head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:8px}
.vote-cand-no{font-weight:600}
.vote-cand-acts{display:flex;flex-wrap:wrap;gap:6px}
.vote-cand-acts .btn{min-height:44px}
.btn.vote-cand-move{min-width:44px;padding:0}
.btn.vote-cand-move:disabled{opacity:.35;cursor:default}
.vote-cand .langs{border-top-color:var(--line-strong)}
.vote-cand-add{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px}
.vote-cand-add small{font-size:12px;color:var(--muted)}
.vote-card{display:grid;gap:2px;padding:12px 14px;border:1px solid var(--line);border-radius:10px;background:var(--surface-2)}
.vote-card small{font-size:12px;color:var(--muted)}
.vote-card strong{font-weight:500;overflow-wrap:anywhere}
.vote-cand-list{list-style:none;margin:0;padding:0;display:grid;border-top:1px solid var(--line)}
.vote-cand-list li,.vote-cand-show{display:flex;align-items:flex-start;gap:12px;padding:12px 0;border-bottom:1px solid var(--line)}
.vote-cand-list li>div,.vote-cand-show>div{display:grid;gap:2px;min-width:0}
.vote-cand-list strong,.vote-cand-show strong{font-weight:500}
.vote-cand-list small,.vote-cand-show small{font-size:13px;color:var(--muted)}
/* Owner 7 Nov 2026 (fix round, VOTE-16): disclosure toggles are touch targets of at least 44px, as the console's other toggles. */
.vote-cand-list details summary,.vote-cand-show details summary,.vote-approval-body summary,.vote-hon-history summary{cursor:pointer;min-height:44px;display:flex;align-items:center;font-size:13px}
.vote-text{white-space:pre-line;margin:0}
.vote-count,.vote-turnout{margin:0 0 10px;font-weight:500}
.vote-table{width:100%;border-collapse:collapse;font-size:14px}
.vote-table th{text-align:left;font-size:13px;font-weight:500;color:var(--muted);padding:8px 12px 8px 0;border-bottom:2px solid var(--ink)}
.vote-table td{padding:10px 12px 10px 0;border-bottom:1px solid var(--line);vertical-align:top;overflow-wrap:anywhere}
.vote-table td.num,.vote-table th+th{white-space:nowrap}
@media (max-width:520px){.vote-table thead{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0)}.vote-table tr{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:2px 12px;padding:10px 0;border-bottom:1px solid var(--line)}.vote-table td{padding:0;border:0}.vote-table td:first-child{grid-column:1/-1;font-weight:500}.vote-table td:nth-child(2),.vote-table td:nth-child(3){font-size:13px;color:var(--muted)}}
.vote-results{list-style:none;margin:0 0 6px;padding:0;display:grid;border-top:1px solid var(--line)}
.vote-results li{display:grid;grid-template-columns:minmax(0,1fr) auto 64px;align-items:center;gap:6px 14px;padding:10px 0;border-bottom:1px solid var(--line)}
.vote-res-name{display:flex;align-items:center;gap:10px;min-width:0;font-weight:500}
.vote-results li>strong{font-weight:600}
.vote-results li>span.num{text-align:right}
.vote-bar{grid-column:1/-1;height:8px;border-radius:4px;background:var(--surface-2);overflow:hidden}
.vote-bar i{display:block;height:100%;border-radius:4px;background:var(--ink)}
.vote-sub{font-size:14px;margin:14px 0 8px}
.vote-approval-choices,.vote-approval-body{margin:12px 0}
.vote-points-form,.vote-withdraw-form{display:grid;gap:14px}
/* Owner 7 Nov 2026 (fix round, FX6-V1): correcting a name on the ballot, under the candidates of the vote's page. */
.vote-names{display:grid;gap:10px;margin-top:14px;justify-items:start}
.vote-names-form{gap:14px;justify-items:stretch;padding-top:14px;border-top:1px solid var(--line)}
.vote-names-form .vote-sub{margin:0}
.vote-names-one{border:0;padding:0;margin:0;display:grid;gap:10px;min-width:0}
.vote-names-one legend{padding:0;margin-bottom:6px;font-weight:600}
.vote-hon{flex:1 1 100%;display:grid;gap:8px;padding:6px 0 2px}
.vote-hon-line{display:flex;flex-wrap:wrap;align-items:center;gap:6px 12px}
.vote-hon-line small{font-size:13px;color:var(--muted)}
.vote-hon-state strong{font-weight:600;color:var(--ink)}
.vote-hon-line .vote-hon-wait{color:var(--wait)}
.vote-hon-line .btn{min-height:44px}
.vote-hon-history summary{color:var(--muted)}
.vote-hon-history ol{margin:4px 0 0;padding-left:18px;display:grid;gap:4px;font-size:13px;color:var(--muted)}
/* The member-page preview: the member page itself in a frame as wide as the device chosen (staff/votes-ui.js memberPage, the member app's
   renderer and /votes/app.css; VOTING-SPEC-TH.md 4.3-4.5, 4.10). Owner 7 Nov 2026 (fix round, VOTE-integration). Was: .vote-pv-* rules that
   drew an approximation here. */
.pv-device.vote-pv-device{overflow:hidden;background:#000}
.vote-who{margin:0;font-size:14px;line-height:1.65}
/* Rule 5 "ข้อความยาว" (19 Oct 2026): a candidate's short line and the dates under the dock's card never leave a lone last word. */
.vote-card small,.vote-cand-list small,.vote-cand-show small,.vote-hon-line small{text-wrap:balance}
/* Owner 7 Nov 2026 (fix round, VOTE-integration; checker notes VOTE-16 [low]): a "คำขอของฉัน" row's small line (the votes list and the Honorary page)
   is balanced, so a long Chinese hint such as "请撤回后修改开始时间" or "等待其他审批人" leaves no word alone on its last line at 390. Was: "时间" and
   "批人" alone. */
.gov-requests .what small{text-wrap:balance}
/* Owner 7 Nov 2026 (fix round, VOTE-integration; the 19 Oct long-text rule, verify-text-wrap.cjs measure): a vote's details and a candidate's
   background on the votes duty's pages leave no one or two characters alone on a last line ("定。" at 390 zh once the samples lost their
   closing "预览用示例数据…" sentence). Was: the browser's default wrapping. */
.prose.vote-text{text-wrap:pretty}
/* Owner 10 Nov 2026 (fix round, FX7-1), next chat: a candidate's member (photo from the profile, name, code) and the member search under it. */
.vote-cand-member{display:flex;align-items:center;gap:12px;padding:8px;border:1px solid var(--line);border-radius:10px;background:var(--surface,#fff);margin:6px 0 10px}
.vote-cand-member .btn{margin-left:auto;flex:none}
.vote-cand-photo{width:48px;aspect-ratio:4/5;border-radius:8px;object-fit:cover;object-position:50% 25%;flex:none;max-width:100%}
.vote-cand-initial{display:grid;place-items:center;background:var(--line);color:var(--ink,#222);font-weight:600}
.vote-cand-who{display:grid;min-width:0}.vote-cand-who small{color:var(--muted,#666)}
/* Fix round 11 Nov item 080: a picked member's box stays inside the form column (it grew to the name's one-line width, under the side panel
   on a 900-1090 px console and past the edge of a phone). The code-and-English line is cut with … inside the box (it stays one line, below). Was: no min-width, so the grid kept the widest line. */
.vote-cands,.vote-cand,.vote-cand>*{min-width:0}.vote-cand-member .vote-cand-who small{overflow:hidden;text-overflow:ellipsis}
.vote-cand-results{list-style:none;margin:0 0 10px;padding:0;display:grid;gap:6px}
.vote-cand-results:empty{display:none}
.vote-cand-pick{display:flex!important;align-items:center;gap:10px;width:100%;text-align:left;justify-content:flex-start}
.vote-cand-pick .vote-cand-photo{width:36px}
.vote-cand-list .vote-cand-photo,.vote-cand-show .vote-cand-photo{width:40px}
/* Owner 11 Nov 2026: a candidate's election application form, and whether a member found is eligible. */
.vote-cand-form{display:grid;gap:4px;margin:0 0 12px}.vote-cand-form .upload{justify-self:start}.vote-cand-file{margin:2px 0}
.vote-cand-pick .state{margin-left:auto;flex:none}.vote-cand-pick:disabled{opacity:.75;cursor:not-allowed}
.vote-cand-form-label{font-weight:500}
.vote-cand-who small{white-space:nowrap}.vote-cand-who strong{overflow-wrap:normal}
@media (max-width:600px){.vote-cand-pick{flex-wrap:wrap}.vote-cand-pick .state{margin-left:46px}}
/* Fix round 11 Nov 2026 (item 138; app rule: a tap area of at least 44x44 px at every width, design/shared-navigation/verify-fix-1111-tap-targets.cjs).
   The look stays: a negative margin keeps the old box where the control grew. Owner rule: the ข่าวสำคัญ order buttons (.slot-acts) may stay
   smaller on narrow screens, so they are not in this list.
   Was: .search 42 · the back chevron 40x40 · บัญชีของฉัน duty links 23.8 · the claim tick box label 24x22 · status bar buttons 38 tall
   (1366) and 23 wide (English 320) · chips 36 (1366) · version/language summaries 32-36 · ติดดาว/โฟลเดอร์/เปิดเคส 40 · folder × 36x40 ·
   เขียนข่าวใหม่ 40 · tick rows 27-36 · ดูในฐานะ 40 · the language box 42 · FAQ set buttons 38 · side-panel tabs 38. */
.search{min-height:44px}
.top select.lang-wide,.who select{min-height:44px}
.title-row>a.back-icon{width:44px;height:44px;min-height:44px;margin:-2px}
.account-duties{gap:0}.account-duties li{min-height:44px}.account-duties a{display:inline-flex;align-items:center;min-height:44px}
.claim-pick{min-width:44px;min-height:44px;margin:-10px;padding:0;align-items:center}
.claim-pick:not(label){min-height:0;margin:0}
.chip,.status-seg button,.dock .tabs button,.gov-faq-sets button,.checks label,.langs summary,.rep-strip a,.rep-chip a,.rep-chip button,.post-new{min-height:44px}
.status-seg button{min-width:44px}
.rep-chip button{min-width:44px}
.check{min-height:44px;align-items:center}
.gov-contract-doc>.gov-contract-versions>summary,.gov-contract-langs>summary{min-height:44px}
/* Item 138: the record link of a restore request ("บันทึก TOSAA-W8K4RT") and "เปิดโหวตนี้" on a vote request are text links; vertical
   padding on an inline link widens its tap area without moving the text around it. Was: 23 and 20 px tall. */
a[data-former-record],a[data-vote-request-open]{padding-block:12px}
/* Item 138: the person switch on a phone's top bar and short duty links ("โหวต") also reach 44 px. Was: 42 tall; "โหวต" 28 wide. */
@media (max-width:900px){.top .who-m{min-height:44px;margin-block:-1px;align-items:center}}
.account-duties a{min-width:44px}
/* item 093 (fix round 11 Nov 2026): the "เวลากันที่นั่ง (นาที)" help text balances its two lines at 320 px, so the last line reads "เมื่อครบเวลา ค่าเริ่มต้น 5 นาที".
   Was: "…ค่าเริ่ม" / "ต้น 5 นาที" (and before the kept words, "นาที" alone). */
.field:has(>input[name=holdMinutes])>small{text-wrap:balance}
/* Fix round 11 Nov 2026 item 140, re-check fix (owner answer ข: the หน้าที่ page may be larger; every other staff page uses one size):
   the section headings of a staff page are one size, 15 px; on the หน้าที่ page (#/work, the page with .duties-head) they are 17 px.
   Was: 15 px (.sec, .dock), 16 px (.band-head, .slots, .compose .sec, .ov-hall-head) and 17 px (.urgent-head), even mixed on one page
   (รายการโหวต: bands 16, 'คำขอของฉัน' 15; หน้าที่: 'งานด่วน' 17, 'เข้ามาใหม่' 15). */
#main.page :is(.sec,.band-head,.dock,.slots,.ov-hall-head,.urgent-head) h2{font-size:15px}
#main.page:has(>.duties-head) :is(.sec,.band-head,.urgent-head) h2{font-size:17px}
