/* Shared stylesheet for the generated biofilm project document pages.
   Signature palette, Google Sans, built to be read on a phone in a plant
   and printed for the file. Restyling every document page is this file. */

@import url('fonts/googlesans.css');
@page { size: A4 portrait; margin: 14mm 15mm; }

:root{
  --ink:#1B1B1B; --blue:#104CD5; --red:#F41B0A;
  --yellow:#F6E53C; --gray:#585C60; --line:#DBDAD9; --tint:#F0EFEE;
  --code:#F5F4F3;
}
*{ box-sizing:border-box; margin:0; padding:0; }
html{ -webkit-text-size-adjust:100%; scroll-padding-top:14px; }
body{
  font-family:'Google Sans','Sarabun',-apple-system,'Segoe UI',Tahoma,sans-serif;
  color:var(--ink); background:var(--tint);
  font-size:16.5px; line-height:1.68;
  padding:18px 12px 60px;
  /* Thai has no inter-word spaces, so never justify and never hyphenate. */
  text-align:left; word-break:normal; line-break:normal;
  hyphens:none; -webkit-hyphens:none; text-wrap:pretty;
  -webkit-font-smoothing:antialiased;
}
.sheet{
  /* Wider than A4 on screen (Boss, 25 Aug 2026: the reading column was too narrow).
     Printing is unaffected: the @media print block below resets this to width:auto. */
  width:240mm; max-width:100%; margin:0 auto; background:#fff;
  padding:14mm 15mm 16mm; border:1px solid var(--line); border-radius:10px;
  box-shadow:0 8px 30px rgba(27,27,27,.10);
}

/* ---------- chrome ---------- */
.crumb{ display:flex; flex-wrap:wrap; gap:6px 18px; margin-bottom:18px; font-size:15px; font-weight:700; }
.crumb a{ color:var(--blue); text-decoration:none; }
.crumb a:hover{ text-decoration:underline; }

header{ border-bottom:3px solid var(--blue); padding-bottom:12px; margin-bottom:22px; }
.kicker{
  display:inline-block; background:var(--yellow); color:var(--ink);
  font-size:12.5px; font-weight:700; letter-spacing:.05em;
  padding:3px 9px; margin-bottom:10px; text-transform:uppercase;
}
h1{ font-size:clamp(23px,4.4vw,31px); font-weight:700; line-height:1.2; color:var(--blue); }
header .meta .updated{ color:var(--blue); font-weight:600; }
.docstatus{ margin-top:12px; padding:9px 12px; border-radius:8px; font-size:13.5px; line-height:1.55;
  border:1px solid var(--line); background:var(--tint); }
.docstatus b{ letter-spacing:.04em; }
.docstatus.current{ border-color:#B7E0CB; background:#F3FBF7; }
.docstatus.current b{ color:#0E7C4A; }
.docstatus.historical{ border-color:#DBDAD9; background:#F5F4F3; color:var(--gray); }
.docstatus.historical b{ color:var(--gray); }
.docstatus.reference{ border-color:#CBD9F6; background:#F4F7FE; }
.docstatus.reference b{ color:var(--blue); }
.docstatus span{ display:block; }
header .meta{ margin-top:9px; font-size:13.5px; color:var(--gray); font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }

/* ---------- Thai orientation block ---------- */
.th-summary{
  border:2px solid var(--blue); padding:16px 18px; margin-bottom:22px;
}
.th-h{
  display:inline-block; background:var(--blue); color:#fff;
  font-size:13px; font-weight:700; letter-spacing:.04em;
  padding:3px 10px; margin-bottom:10px;
}
.th-lead{ font-weight:700; margin-bottom:8px; }
.th-summary ul{ margin:0; }
.th-summary li{ margin-bottom:5px; }
/* Chrome breaks Thai at morpheme boundaries, so ห้องปฏิบัติการ can split as
   ห้อง/ปฏิบัติ/การ. word-break:keep-all does not stop it; nowrap does. The
   build script wraps the affected words (see NOBR_TERMS in build_docs.py). */
.nb{ white-space:nowrap; }

/* ---------- table of contents ---------- */
.toc{ background:var(--tint); padding:14px 18px; margin-bottom:24px; border-left:5px solid var(--yellow); }
.toc-h{ font-size:13px; font-weight:700; letter-spacing:.04em; color:var(--gray); margin-bottom:6px; text-transform:uppercase; }
.toc ol{ list-style:none; counter-reset:toc; columns:2; column-gap:26px; }
.toc li{ counter-increment:toc; padding-left:28px; position:relative; margin-bottom:3px; break-inside:avoid; font-size:15px; }
.toc li::before{ content:counter(toc) "."; position:absolute; left:0; color:var(--blue); font-weight:700; }
/* Headings that number themselves keep their own number; the counter would
   otherwise print it a second time. Same slot, so both kinds stay aligned. */
.toc ol.has-own-numbers > li::before{ content:none; }
.toc li.own-number .n{ position:absolute; left:0; color:var(--blue); font-weight:700; }
.toc a{ color:var(--ink); text-decoration:none; }
.toc a:hover{ color:var(--blue); text-decoration:underline; }

/* ---------- body ---------- */
article h2{
  font-size:21px; font-weight:700; color:var(--blue);
  border-left:9px solid var(--blue); padding-left:11px;
  margin:34px 0 12px; line-height:1.3;
}
article h3{ font-size:18px; font-weight:700; margin:24px 0 7px; }
article h4{ font-size:16.5px; font-weight:700; color:var(--gray); margin:18px 0 5px; }
article p{ margin-bottom:12px; }
/* Opening Project/PI/Date block: one field per line, tighter than paragraph
   spacing so the group still reads as a single header rather than a list. */
.frontmatter{ margin:0 0 18px; padding-left:12px; border-left:3px solid var(--line); }
.frontmatter > div{ margin-bottom:2px; }
.frontmatter > div:last-child{ margin-bottom:0; }
article > *:first-child{ margin-top:0; }

a{ color:var(--blue); }
strong{ font-weight:700; }
del{ color:var(--gray); }

ul,ol{ list-style:none; margin:0 0 14px; }
li{ position:relative; padding-left:20px; margin-bottom:5px; }
ul > li::before{
  content:""; position:absolute; left:5px; top:11px;
  width:6px; height:6px; background:var(--blue);
}
ol{ counter-reset:n; }
ol > li{ counter-increment:n; padding-left:26px; }
ol > li::before{ content:counter(n) "."; position:absolute; left:0; color:var(--blue); font-weight:700; }
ul.sub, ol .sub{ margin:5px 0 5px 14px; }

/* task list checkboxes, rendered from - [ ] and - [x] */
ul.task > li{ padding-left:28px; }
ul.task > li::before{ display:none; }
.cb{
  position:absolute; left:0; top:5px;
  width:15px; height:15px; border:2px solid var(--ink); background:#fff;
}
.cb.on{ background:var(--blue); border-color:var(--blue); }
.cb.on::after{
  content:""; position:absolute; left:3px; top:0px;
  width:5px; height:9px; border:solid #fff; border-width:0 2px 2px 0;
  transform:rotate(45deg);
}

blockquote{
  border-left:5px solid var(--yellow); background:var(--tint);
  padding:12px 16px; margin:0 0 16px;
}
blockquote > *:last-child{ margin-bottom:0; }

hr{ border:0; border-top:1px solid var(--line); margin:26px 0; }

code{
  font-family:ui-monospace,SFMono-Regular,Menlo,monospace;
  font-size:.88em; background:var(--code); padding:1px 5px; border-radius:3px;
  word-break:break-word;
}
pre{
  background:var(--ink); color:#F2F1F1; padding:14px 16px; margin:0 0 16px;
  overflow-x:auto; border-radius:6px; font-size:13.5px; line-height:1.5;
}
pre code{ background:none; padding:0; color:inherit; font-size:inherit; white-space:pre; word-break:normal; }

/* wide tables scroll inside their own box so the page never scrolls sideways */
.tw{ overflow-x:auto; margin:0 0 18px; -webkit-overflow-scrolling:touch; }
table{ border-collapse:collapse; width:100%; min-width:520px; font-size:15px; }
th,td{ border:1px solid var(--line); padding:7px 10px; text-align:left; vertical-align:top; }
th{ background:var(--blue); color:#fff; font-weight:700; position:sticky; top:0; }
tbody tr:nth-child(even){ background:var(--tint); }

footer{
  margin-top:38px; padding-top:14px; border-top:1px solid var(--line);
  font-size:13.5px; color:var(--gray); line-height:1.5;
}

.pdfbtn{
  position:fixed; right:14px; bottom:14px; z-index:50;
  width:46px; height:46px; border:0; border-radius:50%; cursor:pointer;
  font-size:19px; line-height:1; color:#fff; background:var(--blue);
  box-shadow:0 3px 10px rgba(16,76,213,.28), 0 10px 26px rgba(16,76,213,.22);
}
.pdfbtn:hover{ background:var(--red); }
.pdfbtn:focus-visible{ outline:3px solid var(--red); outline-offset:3px; }

@media (max-width:620px){
  body{ font-size:16px; padding:12px 8px 60px; }
  .sheet{ padding:16px 14px 22px; border-radius:8px; }
  .toc ol{ columns:1; }
  article h2{ font-size:19px; margin-top:26px; }
  table{ font-size:14px; }
}

@media print{
  body{ background:#fff; padding:0; font-size:10.5pt;
        -webkit-print-color-adjust:exact; print-color-adjust:exact; }
  .sheet{ width:auto; border:0; border-radius:0; box-shadow:none; padding:0; }
  .crumb, .pdfbtn, .toc{ display:none !important; }
  .tw{ overflow:visible; }
  table{ min-width:0; font-size:9pt; }
  th{ position:static; }
  article h2{ break-after:avoid; }
  .tw, blockquote, pre, .th-summary{ break-inside:avoid; }
  a{ color:var(--ink); text-decoration:none; }
}

/* ---------- CV page (sidebar + timeline template) ---------- */
.cv-sheet{
  width:210mm; max-width:100%; margin:0 auto; background:#fff;
  border:1px solid var(--line); border-radius:10px; overflow:hidden;
  box-shadow:0 8px 30px rgba(27,27,27,.10);
}
.cv-crumbwrap{ padding:14mm 15mm 0; }

.cv-frame{ display:flex; align-items:stretch; }

/* sidebar */
.cv-side{ width:34%; flex:none; background:var(--ink); color:#fff; padding:34px 24px; }
.cv-avatar{
  width:150px; height:150px; border-radius:50%; object-fit:cover; display:block;
  margin:0 auto 26px; border:3px solid rgba(255,255,255,.18);
}
.cv-side-block{ margin-bottom:28px; }
.cv-side-block:last-child{ margin-bottom:0; }
.cv-side-h{
  font-size:12px; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
  color:#fff; margin-bottom:13px; padding-bottom:7px; border-bottom:1px solid rgba(255,255,255,.2);
}
.cv-side-list{ list-style:none; font-size:12.5px; line-height:1.7; }
.cv-side-list li{ padding-left:0; margin-bottom:8px; color:rgba(255,255,255,.82); word-break:break-word; }
.cv-side-list li:last-child{ margin-bottom:0; }
.cv-side-list li::before{ display:none; }
.cv-side-list a{ color:#fff; text-decoration:underline; text-underline-offset:2px; }
.cv-side-edu{ margin-bottom:15px; }
.cv-side-edu:last-child{ margin-bottom:0; }
.cv-side-edu .deg{ font-size:12.5px; font-weight:700; color:#fff; line-height:1.4; }
.cv-side-edu .inst{ font-size:11.5px; color:rgba(255,255,255,.68); margin-top:2px; }
.cv-side-edu .yr{ font-size:11px; color:rgba(255,255,255,.5); margin-top:2px; font-weight:600; }
.cv-side-tags{ display:flex; flex-wrap:wrap; gap:7px; }
.cv-side-tags span{ font-size:11px; padding:4px 10px; border:1px solid rgba(255,255,255,.28); border-radius:999px; color:#fff; }
.cv-side-note{ font-size:12px; color:rgba(255,255,255,.72); line-height:1.6; }

/* main column */
.cv-main{ flex:1; min-width:0; padding:36px 32px; }
.cv-title h1{ font-size:clamp(24px,4vw,30px); font-weight:700; color:var(--ink); letter-spacing:-.01em; line-height:1.15; }
.cv-title-role{ font-size:12.5px; font-weight:700; color:var(--blue); letter-spacing:.05em; margin-top:8px; }
.cv-title-sub{ font-size:13.5px; color:var(--gray); margin-top:4px; }
.cv-bio{ font-size:13.5px; color:var(--ink); line-height:1.68; margin-top:20px; }

.cv-main-h{
  display:flex; align-items:center; gap:9px;
  font-size:12.5px; font-weight:700; letter-spacing:.1em; text-transform:uppercase;
  color:var(--ink); margin:28px 0 16px;
}
.cv-main-h::before{ content:""; width:9px; height:9px; border-radius:50%; background:var(--blue); flex:none; }

.cv-frame-box{ border:1px solid var(--line); border-radius:12px; padding:6px 18px; }
.cv-frame-box .cv-pub-item:first-child{ padding-top:12px; }
.cv-frame-box .cv-pub-item:last-child{ padding-bottom:12px; }

/* CMUPSF / CMUIDP badge wall, in the main column under Selected
   Publications. No section heading: the wordmark names it, so the wordmark
   is the one piece that has to survive into print. Wordmark and badges are
   both centred, as one block. Flex rather than grid so the short second row
   centres under the first instead of hanging left; a fixed flex basis is
   what makes it break 4 + 3. The badge PNGs are
   transparent only outside the ring, so they drop onto white as they are.
   Base li styles add a bullet and left padding, both switched off here. */
.cv-badges-mark{ margin:28px 0 12px; }
.cv-badges-mark img{ width:104px; height:auto; display:block; margin:0 auto; }
.cv-badges{
  list-style:none; display:flex; flex-wrap:wrap; justify-content:center;
  gap:12px 8px; margin:0;
}
.cv-badges li{
  display:flex; flex-direction:column; align-items:center; text-align:center;
  gap:5px; padding-left:0; margin:0; flex:0 0 104px;
}
.cv-badges li::before{ display:none; }
.cv-badges img{ width:100%; max-width:56px; height:auto; display:block; }
.cv-badges .code{
  font-size:10px; font-weight:700; color:var(--ink);
  letter-spacing:.02em; white-space:nowrap;
}
.cv-badges .name{ font-size:9px; line-height:1.3; color:var(--gray); }

.cv-timeline{ margin-left:4px; }
.cv-tl-item{ position:relative; padding-left:24px; padding-bottom:22px; border-left:2px solid var(--line); }
.cv-tl-item:last-child{ padding-bottom:0; border-left-color:transparent; }
.cv-tl-item::before{
  content:""; position:absolute; left:-7px; top:1px;
  width:12px; height:12px; border-radius:50%; background:#fff; border:2px solid var(--blue);
}
.cv-tl-role{ font-size:14px; font-weight:700; color:var(--ink); }
.cv-tl-role .org{ font-weight:400; color:var(--gray); }
.cv-tl-dates{ font-size:11px; font-weight:700; color:var(--blue); letter-spacing:.04em; text-transform:uppercase; margin-top:3px; }

/* publication sections below the fold */
.cv-below{ padding:6px 15mm 16mm; }
.cv-pub-list{ display:flex; flex-direction:column; }
.cv-pub-item{ display:grid; grid-template-columns:44px 1fr; gap:12px; padding:8px 0; border-bottom:1px solid var(--line); }
.cv-pub-item:last-child{ border-bottom:none; }
.cv-pub-year{ font-weight:700; color:var(--red); font-size:13px; padding-top:1px; }
.cv-pub-title{ font-size:13.5px; font-weight:700; margin-bottom:2px; line-height:1.4; }
.cv-pub-meta{ font-size:12px; color:var(--gray); }

@media (max-width:700px){
  .cv-frame{ flex-direction:column; }
  .cv-side{ width:100%; }
  .cv-crumbwrap{ padding:16px 16px 0; }
  .cv-main{ padding:28px 20px; }
  .cv-below{ padding:6px 16px 24px; }
}

@media print{
  .cv-sheet{ width:auto; border:0; border-radius:0; box-shadow:none; }
  /* Standardized on Chrome's "Default" print margin (@page's own 14mm/15mm
     below, honored automatically) so counter(page)/counter(pages) page
     numbers can render, they need real margin-box space and go blank
     under "Minimum". That cost the full-bleed sidebar look; this padding
     is now just ordinary interior spacing on top of the page margin, not
     a workaround for a collapsed one. */
  /* Sidebar's own content (avatar + 4 blocks) doesn't naturally reach the
     bottom of a full A4 page, even though .cv-frame stretches the column
     itself the full page height. Flex + space-between distributes the
     leftover vertical space evenly into the gaps between sections instead
     of leaving it all bunched as one blank strip under Licensure, so the
     photo stays at top and Licensure lands at the true bottom. */
  .cv-side{
    -webkit-print-color-adjust:exact; print-color-adjust:exact; padding:20px 14px;
    display:flex; flex-direction:column; justify-content:space-between;
  }
  .cv-tl-item, .cv-pub-item{ break-inside:avoid; }
  .cv-crumbwrap{ padding:0; }

  /* compact sizing so the full publication record fits in fewer pages */
  .cv-avatar{ width:126px; height:126px; margin-bottom:16px; }
  .cv-side-block{ margin-bottom:14px; }
  .cv-side-h{ font-size:10pt; margin-bottom:6px; padding-bottom:3px; }
  .cv-side-list{ font-size:9.5pt; line-height:1.5; }
  .cv-side-list li{ margin-bottom:4px; }
  .cv-side-edu{ margin-bottom:7px; }
  .cv-side-edu .deg{ font-size:9.5pt; }
  .cv-side-edu .inst, .cv-side-edu .yr{ font-size:8.5pt; }
  .cv-side-tags span{ font-size:8.5pt; padding:3px 9px; }
  .cv-side-note{ font-size:8.5pt; line-height:1.4; }

  .cv-main{ padding:11px 16px; }
  .cv-title h1{ font-size:17.5pt; }
  .cv-title-role{ font-size:8.5pt; margin-top:6px; }
  .cv-title-sub{ font-size:9.5pt; margin-top:4px; }
  .cv-bio{ font-size:8.8pt; line-height:1.32; margin-top:14px; }

  /* Section headers (Work Experience, Selected Publications, and every
     heading below the fold: Research Grants, Full Paper Publications,
     Proceedings, Abstracts) all share this one size now, so the record
     reads as one consistent document rather than a large "cover" page
     followed by a visibly smaller dense list. */
  .cv-main-h{ font-size:10pt; margin:15px 0 8px; gap:6px; }
  .cv-main-h::before{ width:6px; height:6px; }
  .cv-frame-box{ padding:4px 16px; border-radius:8px; }
  .cv-frame-box .cv-pub-item{ padding:4px 0; }
  .cv-frame-box .cv-pub-title{ line-height:1.3; }
  .cv-frame-box .cv-pub-meta{ line-height:1.3; }
  .cv-frame-box .cv-pub-item:first-child{ padding-top:10px; }
  .cv-frame-box .cv-pub-item:last-child{ padding-bottom:10px; }

  /* page 1 = sidebar + Work Experience + Selected Publications only;
     everything below the fold starts fresh on page 2. min-height fills
     the frame out to the full printable page height so the sidebar's dark
     column runs the full height of page 1 instead of stopping short and
     leaving a blank gap before the forced break. */
  .cv-frame{ min-height:100vh; }
  .cv-below > .cv-main-h:first-child{ break-before:page; margin-top:0; }

  .cv-tl-item{ padding-left:18px; padding-bottom:12px; }
  .cv-tl-item::before{ width:9px; height:9px; left:-5px; }
  .cv-tl-role{ font-size:8.8pt; }
  .cv-tl-dates{ font-size:7.6pt; margin-top:3px; }

  /* box-decoration-break:clone re-applies this padding at every page the
     block gets fragmented across, not just the first/last, so a page the
     content happens to overflow onto mid-list still gets a top margin.
     Under "Default" print margin @page's own 14mm/15mm already does this
     job natively per physical page, so this is now belt-and-suspenders
     rather than load-bearing, kept in case the margin setting changes. */
  .cv-below{
    padding:8mm 12mm;
    box-decoration-break:clone; -webkit-box-decoration-break:clone;
  }
  /* Full record entries (Research Grants onward) now match the Selected
     Publications sizing on page 1, per Boss's request that the whole
     document read at one consistent text size rather than shrinking
     after the fold. This is a real trade-off, page count grows since
     20+ dense entries at a larger size take more room; see commit
     message / session log for the resulting count. */
  .cv-pub-item{ grid-template-columns:30px 1fr; gap:8px; padding:8px 0; }
  .cv-pub-year{ font-size:8pt; }
  .cv-pub-title{ font-size:8.5pt; line-height:1.35; margin-bottom:1px; }
  .cv-pub-meta{ font-size:7.5pt; line-height:1.3; }

  /* Badge wall, sized to the main column's leftover print budget so the frame
     still ends inside page 1. Measured against the real 680px print width,
     not estimated. The wordmark is the section's only label (there is no
     heading), so unlike the rest of the block it has to print.

     margin-top:auto with the column as a flex box drops the block to the
     foot of the page instead of leaving it stranded mid-column: the sidebar
     already runs the full page height, so without this the main column ends
     ~35px short and page 1 reads as unfinished. */
  .cv-main{ display:flex; flex-direction:column; }
  /* margin-top:auto pins the badge block to the foot of the column so its
     bottom lines up with the sidebar's, whatever slack is left over. The
     padding-top is the floor: when there is no slack, auto collapses to 0
     and the block would otherwise butt straight against the box above. */
  .cv-badges-mark{ margin:0 0 8px; margin-top:auto; padding-top:15px; }
  .cv-badges-mark img{ width:86px; }
  .cv-badges{ gap:8px; break-inside:avoid; }
  .cv-badges li{ flex:0 0 92px; }
  .cv-badges img{ max-width:50px; }
  .cv-badges .code{ font-size:7.5pt; }
  .cv-badges .name{ font-size:6.5pt; line-height:1.15; }

  /* Page 2 onward (Research Grants through Abstract Proceedings) sized a
     notch below page 1 to keep the page count down. Page 1 is untouched:
     these selectors are scoped to .cv-below rather than changing the shared
     base rules above. */
  .cv-below .cv-main-h{ font-size:9pt; margin:16px 0 10px; }
  .cv-below .cv-pub-item{ padding:6px 0; }
  .cv-below .cv-pub-year{ font-size:8.3pt; }
  .cv-below .cv-pub-title{ font-size:8.7pt; line-height:1.3; }
  .cv-below .cv-pub-meta{ font-size:7.6pt; line-height:1.28; }
}
