/* From web/src/styles.css (draft styling of the first design). Additions for the server-rendered pages at the end. */

/* DB Ozone X served with the site (2026-11-04): phones do not have it installed, so they fell back to Noto Sans Thai /
   Thonburi, which look much bigger at the sizes below (tuned for DB Ozone X). Same woff2 files as 0409_gamified_member.
   600 (semi-bold labels) uses Medium, 700 Bold. */
@font-face { font-family: 'DB Ozone X'; src: url('../fonts/DBOzoneX-Regular.woff2') format('woff2'); font-weight: 100 400; font-style: normal; font-display: swap; }
@font-face { font-family: 'DB Ozone X'; src: url('../fonts/DBOzoneX-Medium.woff2') format('woff2'); font-weight: 500 600; font-style: normal; font-display: swap; }
@font-face { font-family: 'DB Ozone X'; src: url('../fonts/DBOzoneX-Bold.woff2') format('woff2'); font-weight: 700 900; font-style: normal; font-display: swap; }
:root {
  /* font scale: 1 on phones, larger on big screens (see media query at the end) */
  --fs: 1;
  --navy: #173f96;
  --navy-dark: #10306f;
  --title: #1d3f8f;
  --text: #1f2937;
  --muted: #6b7280;
  --line: #e5e7eb;
  --surface: #ffffff;
  --soft: #eef4ff;
  --onsite: #c27803;      /* amber, close to the GPF logo yellow; distinct from the green "open" status */
  --onsite-bg: #fff3d6;
  --success: #16a34a;
  --success-bg: #e7f6ec;
  --online: #2f6fe4;
  --online-bg: #e6eefc;
  --closed: #a3a9b4;
  --danger: #c62828;
  --danger-bg: #fdecec;
  --sunday: #d64545;
  --radius-card: 28px;
  --radius: 14px;
  --font: 'DB Ozone X', 'Noto Sans Thai', 'Sarabun', 'Leelawadee UI', Tahoma, system-ui, sans-serif;
}

* { box-sizing: border-box; }

html, body { height: 100%; }

body {
  margin: 0;
  font-family: var(--font);
  color: var(--text);
  background: #3a9bf4 linear-gradient(135deg, #38a6f5 0%, #4f8ef0 55%, #5a7fe6 100%) fixed;
  -webkit-font-smoothing: antialiased;
}

button, input { font: inherit; }

/* ---------- Layout ---------- */
.shell {
  /* App-like: header + card exactly fill the viewport. The page never scrolls; the card scrolls inside. */
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* side gutter so the white card never touches the screen edge (design: blue frame around the card) */
  padding: 0 max(16px, env(safe-area-inset-right)) 0 max(16px, env(safe-area-inset-left));
  background-size: cover;
  background-position: center top;
  background-repeat: no-repeat;
}

.shell-header {
  width: 100%;
  padding: max(16px, env(safe-area-inset-top)) 16px 14px;
  text-align: center;
  color: #fff;
}
.shell-header h1 { margin: 0; font-size: calc(22px * var(--fs)); font-weight: 700; letter-spacing: .2px; }

.card {
  flex: 1 1 auto;
  min-height: 0;
  width: 100%;
  max-width: 560px;
  background: var(--surface);
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  /* no bottom padding: the sticky action bar sits on the bottom edge and carries the padding itself */
  padding: 24px 20px 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  box-shadow: 0 -2px 24px rgba(16, 48, 111, .08);
}
/* The card is the scroll box: its children keep their own height. Without this a child with overflow:hidden (the
   member card) was squeezed to the space left and cut its last rows, and nothing scrolled (bug 2026-11-04). */
.card > :not(.spacer) { flex-shrink: 0; }
/* keep some space under the last item on pages without an action bar */
.card > :last-child:not(.sticky-actions):not(.calendar-page):not(form) { margin-bottom: 24px; }

/* Very short screens (landscape phones): fall back to normal page scrolling. */
@media (max-height: 560px) {
  .shell { height: auto; min-height: 100dvh; overflow: visible; }
  .card { overflow: visible; }
}

@media (min-width: 600px) {
  .shell-header { padding-top: 32px; }
  .card { margin-bottom: 32px; border-radius: var(--radius-card); }
}

.page-title { margin: 0; color: var(--title); font-size: calc(26px * var(--fs)); font-weight: 700; line-height: 1.3; }
.page-sub { margin: 2px 0 16px; color: var(--muted); font-size: calc(18px * var(--fs)); }

.back {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--text); text-decoration: none; font-size: calc(19px * var(--fs)); margin-bottom: 14px;
  background: none; border: 0; padding: 0; cursor: pointer;
}

.spacer { flex: 1; }

/* ---------- Buttons ---------- */
.btn {
  display: block; width: 100%;
  border: 0; border-radius: 10px;
  padding: 11px 16px;
  font-size: calc(18px * var(--fs)); font-weight: 700;
  cursor: pointer; text-align: center; text-decoration: none;
}
.btn-primary { background: var(--navy); color: #fff; box-shadow: 0 6px 14px rgba(23, 63, 150, .25); }
.btn-primary:hover { background: var(--navy-dark); }
.btn-primary:disabled { background: #b8c2d8; box-shadow: none; cursor: not-allowed; }
.btn-ghost { background: #fff; color: var(--navy); border: 1.5px solid var(--navy); }
.btn + .btn { margin-top: 10px; }
.sticky-actions {
  position: sticky; bottom: 0; z-index: 2;
  background: linear-gradient(to top, #fff 75%, rgba(255,255,255,0));
  padding: 16px 0 calc(20px + env(safe-area-inset-bottom));
  margin-top: 16px;
}

/* ---------- Calendar ---------- */
.month-nav {
  display: flex; align-items: center; justify-content: space-between;
  background: var(--soft); border-radius: var(--radius); padding: 8px;
}
.month-nav .label { text-align: center; }
.month-nav .label strong { display: block; font-size: calc(22px * var(--fs)); color: var(--text); }
.month-nav .label span { font-size: calc(17px * var(--fs)); color: var(--muted); }
.icon-btn {
  width: 40px; height: 40px; border-radius: 10px; border: 0;
  background: #fff; color: var(--navy); cursor: pointer;
  display: grid; place-items: center; box-shadow: 0 1px 3px rgba(0,0,0,.08);
}
.icon-btn:disabled { background: transparent; color: #c3c9d4; box-shadow: none; cursor: default; }
.calendar-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.today-chip {
  flex: none; display: inline-flex; align-items: center; gap: 6px; padding: 6px 14px; border-radius: 999px;
  background: var(--online-bg); color: var(--navy); font-size: calc(16px * var(--fs)); font-weight: 600; text-decoration: none;
}
.today-chip:hover { background: #d6e3fb; }

/* Scroll to top (calendar): round button bottom right, above the safe area. */
.to-top {
  position: fixed; right: max(16px, env(safe-area-inset-right)); bottom: calc(20px + env(safe-area-inset-bottom)); z-index: 20;
  width: 48px; height: 48px; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--navy); color: #fff; display: grid; place-items: center; box-shadow: 0 4px 14px rgba(16, 48, 111, .3);
}
.to-top[hidden] { display: none; }

/* minmax(0, 1fr) + fluid day width: 7 columns always fit, even on 320px phones */
.cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); row-gap: 6px; margin-top: 14px; text-align: center; }
.cal .dow { font-size: calc(17px * var(--fs)); color: var(--muted); padding: 4px 0 8px; }
.cal .dow.sun { color: var(--sunday); }
.day {
  position: relative; height: 44px; margin: 0 auto; width: 100%; max-width: 44px; padding: 0;
  border-radius: 10px; border: 1.5px solid transparent; background: none;
  font-size: calc(19px * var(--fs)); color: var(--text); cursor: default;
}
.day.has-events { cursor: pointer; }
.day.today { border-color: var(--navy); font-weight: 700; }
.day.selected { background: var(--navy); color: #fff; font-weight: 700; }
.day .dots { position: absolute; left: 0; right: 0; bottom: 5px; display: flex; justify-content: center; gap: 3px; }
.dot { width: 5px; height: 5px; border-radius: 50%; display: inline-block; background: var(--online); }
.day.selected .dot { background: #fff; }

.legend { display: flex; gap: 16px; font-size: calc(17px * var(--fs)); color: var(--muted); margin: 12px 0 4px; align-items: center; }
.legend .item { display: inline-flex; align-items: center; gap: 6px; }
.legend .today-box { width: 11px; height: 11px; border: 1.5px solid var(--navy); border-radius: 3px; }

.day-list { border-top: 1px solid var(--line); margin-top: 14px; padding-top: 14px; }
.day-list h3 { margin: 0 0 10px; font-size: calc(20px * var(--fs)); }

/* ---------- Event card / badges ---------- */
.event-card {
  display: flex; align-items: center; gap: 10px;
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 12px 14px; color: inherit; text-decoration: none; background: #fff;
}
.event-card + .event-card { margin-top: 10px; }
.event-card:hover { border-color: #c8d3ea; }
.event-card .body { flex: 1; min-width: 0; }
/* Long names: 3 lines then "…" on the card; the detail page shows the full name. */
.event-card .title {
  font-weight: 700; font-size: calc(20px * var(--fs)); line-height: 1.4; margin: 0 0 6px;
  display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; line-clamp: 3;
  overflow: hidden; overflow-wrap: anywhere;
}
.event-card .meta { color: var(--muted); font-size: calc(18px * var(--fs)); margin-top: 6px; }

.badge { display: inline-block; align-self: flex-start; font-size: calc(16px * var(--fs)); padding: 2px 10px; border-radius: 999px; font-weight: 600; }
.badge.onsite { background: var(--onsite-bg); color: var(--onsite); }
.badge.online { background: var(--online-bg); color: var(--online); }
.badge.closed { background: #f1f2f4; color: var(--muted); }

.empty { color: var(--muted); text-align: center; padding: 24px 0; font-size: calc(19px * var(--fs)); }

/* Calendar page: a normal long page. The card grows with the event list and the whole page scrolls
   (no fixed height, no inner scroll box). */
.shell:has(.calendar-page) { height: auto; min-height: 100vh; min-height: 100dvh; overflow: visible; }
.card:has(.calendar-page) { flex: 1 0 auto; overflow: visible; padding-bottom: 0; }
.calendar-page .day-list { padding-top: 0; padding-bottom: calc(16px + env(safe-area-inset-bottom)); }
.calendar-page .list-head { padding: 14px 0 8px; margin: 0; }
.calendar-page .cal { row-gap: 2px; }
.calendar-page .day { height: 40px; max-width: 40px; }

/* Whole-month list under the calendar */
.list-head { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 6px; }
.list-head h3 { margin: 0; }
.day-group { padding: 10px 0 4px; scroll-margin-top: 12px; }
/* "กิจกรรมที่กำลังจะเกิดขึ้น" / "กิจกรรมที่ผ่านมาแล้ว" above the day groups */
.list-section { margin: 14px 0 0; padding-top: 10px; font-size: calc(19px * var(--fs)); color: var(--title); border-top: 1px dashed var(--line); }
.list-head + .list-section { margin-top: 0; padding-top: 0; border-top: 0; }
.day-group h4 { margin: 0 0 8px; font-size: calc(18px * var(--fs)); color: var(--muted); font-weight: 600; }
.day-group.selected h4 { color: var(--navy); }
.day-group.selected .event-card { border-color: var(--navy); box-shadow: 0 0 0 1px var(--navy) inset; }
.event-card .badges { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.status { font-size: calc(16px * var(--fs)); font-weight: 600; display: inline-flex; align-items: center; gap: 5px; }
.status::before { content: ''; width: 7px; height: 7px; border-radius: 50%; background: currentColor; }
.status.open { color: var(--success); }
.status.closed { color: var(--muted); }

/* ---------- Detail ---------- */
/* Banner at full width and its own height (never cropped). flex: none: the card is a flex column and overflow:hidden
   would otherwise let it shrink the image to nothing. */
.hero { flex: none; border-radius: var(--radius); overflow: hidden; margin-bottom: 16px; }
.hero img { display: block; width: 100%; height: auto; }
/* baseline: an SVG's baseline is its bottom edge, so the icon bottom sits on the text baseline (first line) */
.info-row { display: flex; gap: 10px; align-items: baseline; margin: 8px 0; font-size: calc(19px * var(--fs)); }
.info-row svg { flex: 0 0 auto; color: var(--navy); position: relative; top: 2px; }
.section-title { font-weight: 700; margin: 20px 0 6px; font-size: calc(21px * var(--fs)); color: var(--text); }  /* above the 19px description */
.description { color: #374151; line-height: 1.6; font-size: calc(19px * var(--fs)); }
/* pre-line on the paragraphs only: whitespace between the <p> tags in the markup must not show */
.description p { white-space: pre-line; margin: 0 0 8px; }
.description p:last-child { margin-bottom: 0; }

/* ---------- Forms ---------- */
.field { margin-bottom: 14px; }
.field label { display: block; font-size: calc(18px * var(--fs)); font-weight: 600; margin-bottom: 6px; }
.field input, .field textarea {
  width: 100%; padding: 12px 14px; font-size: calc(20px * var(--fs));
  border: 1.5px solid var(--line); border-radius: 10px; outline: none; background: #fff;
}
.field textarea { resize: vertical; min-height: 84px; line-height: 1.5; font: inherit; font-size: calc(19px * var(--fs)); }
.field input:focus, .field textarea:focus { border-color: var(--online); box-shadow: 0 0 0 3px rgba(47,111,228,.15); }
.field.error input, .field.error textarea { border-color: var(--danger); }
.field .hint { font-size: calc(17px * var(--fs)); color: var(--muted); margin-top: 4px; }
.field .hint.right { text-align: right; }
.field .optional { font-weight: 400; color: var(--muted); }

/* Register form (design draft 3) */
.link-blue { color: var(--navy); }
/* Event info under the form title: one fact per line */
.event-info { background: var(--soft); border-radius: var(--radius); padding: 12px 14px; margin: 10px 0 18px; }
.event-info .event-title { font-weight: 700; font-size: calc(20px * var(--fs)); line-height: 1.4; margin-bottom: 4px; }
.event-info .info-row { margin: 4px 0; font-size: calc(18px * var(--fs)); color: #374151; }
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.register-form { display: flex; flex-direction: column; flex: 1; }
.consent { display: flex; gap: 10px; align-items: baseline; font-size: calc(19px * var(--fs)); line-height: 1.5; cursor: pointer; }
.consent input { width: 22px; height: 22px; margin: 0; accent-color: var(--navy); flex: 0 0 auto; position: relative; top: 1px; }
.privacy-link { color: var(--online); }
.field .err { font-size: calc(17px * var(--fs)); color: var(--danger); margin-top: 4px; }
.row-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 360px) { .row-2 { grid-template-columns: 1fr; } }

.alert { border-radius: 10px; padding: 12px 14px; font-size: calc(18px * var(--fs)); margin-bottom: 14px; }
.alert.error { background: var(--danger-bg); color: var(--danger); }
.alert.info { background: var(--soft); color: var(--title); }

.summary { background: var(--soft); border-radius: var(--radius); padding: 4px 14px; margin: 12px 0; }
.summary .line { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 10px 0; border-bottom: 1px solid #dbe5fb; font-size: calc(19px * var(--fs)); }
.summary .line:last-child { border-bottom: 0; }
.summary .line span:first-child { color: var(--muted); }
.summary .line span:last-child { font-weight: 600; text-align: right; word-break: break-all; }
.summary .line.emph span:last-child { color: var(--navy); font-size: calc(20px * var(--fs)); }
.summary.plain { background: #fff; border: 1px solid var(--line); }
.summary.plain .line { border-bottom-color: var(--line); }
.summary .line .ellipsis { max-width: 65%; }

.event-mini { border: 1px solid var(--line); border-radius: var(--radius); padding: 12px 14px; margin-bottom: 18px; }
.event-mini .title { font-weight: 700; margin: 4px 0 2px; }
.event-mini .meta { color: var(--muted); font-size: calc(18px * var(--fs)); }

/* ---------- Result ---------- */
.result { text-align: center; padding: 16px 0 8px; }
.result .icon { width: 84px; height: 84px; border-radius: 50%; display: grid; place-items: center; margin: 8px auto 16px; }
.result .icon.ok { background: var(--success-bg); color: var(--success); }
.result .icon.warn { background: #fff4e5; color: #c77700; }
.result h2 { color: var(--title); margin: 0 0 8px; font-size: calc(26px * var(--fs)); }
.result p { color: #374151; margin: 0 0 6px; line-height: 1.6; }

.mock-note { font-size: calc(16px * var(--fs)); color: var(--muted); text-align: center; margin-top: 14px; }
.spinner { width: 28px; height: 28px; border: 3px solid var(--soft); border-top-color: var(--navy); border-radius: 50%; animation: spin .8s linear infinite; margin: 40px auto; }
@keyframes spin { to { transform: rotate(360deg); } }

/* ---------- Part 2: app check-in ---------- */
.center { text-align: center; }
.identity { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 18px; text-align: center; }
.identity-title { font-size: calc(24px * var(--fs)); font-weight: 700; color: var(--text); margin-bottom: 4px; }
.identity p { margin: 0 0 14px; color: #374151; font-size: calc(20px * var(--fs)); }
.identity p strong { color: var(--text); }
.queue-box {
  margin: 0 auto; width: 180px; background: var(--soft); border-radius: var(--radius);
  padding: 10px 12px; display: flex; flex-direction: column; align-items: center;
}
.queue-box span { color: var(--online); font-size: calc(18px * var(--fs)); }
.queue-box strong { color: var(--navy); font-size: calc(42px * var(--fs)); line-height: 1.1; }
.queue-no { color: var(--navy); font-size: calc(24px * var(--fs)) !important; }
.row-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.row-actions .btn + .btn { margin-top: 0; }

/* 3B: member card (masked profile) */
.member-card { border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; margin-bottom: 8px; }
/* Phones: label on its own line, the value under it at full width (a long label next to the value broke the masked
   citizen id one character per line). Big screens: label left, value right. */
.member-row {
  display: grid; grid-template-columns: 22px 1fr; grid-template-areas: "icon label" ". value";
  align-items: baseline; column-gap: 8px; row-gap: 2px; padding: 12px 14px; border-bottom: 1px solid var(--line);
}
.member-row:last-child { border-bottom: 0; }
.member-icon { grid-area: icon; color: var(--navy); position: relative; top: 3px; }
.member-label { grid-area: label; color: var(--muted); font-size: calc(17px * var(--fs)); }
.member-value { grid-area: value; font-size: calc(20px * var(--fs)); font-weight: 600; color: var(--text); overflow-wrap: anywhere; letter-spacing: .3px; }
@media (min-width: 600px) {
  .member-row { grid-template-columns: 22px auto 1fr; grid-template-areas: "icon label value"; }
  .member-label { white-space: nowrap; }
  .member-value { text-align: right; }
}

/* Shared closing page */
.result.end { padding-top: 40px; }
.result .icon.info { background: var(--soft); color: var(--navy); }
.result.end p { font-size: calc(20px * var(--fs)); line-height: 1.7; }
/* "โปรดติดตามกิจกรรมอื่น ๆ ได้ที่ ..." (check-in not open, month without events, end page) */
.follow-us { margin: 18px 0 0; color: var(--title); font-weight: 600; font-size: calc(19px * var(--fs)); line-height: 1.7; text-align: center; }
.result p.follow-us { color: var(--title); margin-top: 40px; }
/* Check-in not open: "กรุณาสแกนอีกครั้ง" and the date line, 2 steps above the default 16px (2026-11-05). */
.result p.not-open-prompt, .result p.not-open-detail { font-size: calc(19px * var(--fs)); }
.result .event-name { font-weight: 600; color: var(--text); font-size: calc(20px * var(--fs)); line-height: 1.5; margin: 0 0 10px; }
.empty p { margin: 0; }

/* Larger screens: the card is a narrow column on a big screen, so scale the text up a bit.
   (Fonts only — no zoom, so heights computed from the viewport stay exact.) */
@media (min-width: 768px) {
  :root { --fs: 1.12; }
  .card { max-width: 600px; }
  /* Buttons: full width on phones, a centred fixed width on big screens (text not scaled up). */
  .btn { font-size: 17px; padding: 10px 16px; max-width: 320px; margin-left: auto; margin-right: auto; }
  .sticky-actions.row-actions, .dialog .row-actions { width: 100%; max-width: 440px; margin-left: auto; margin-right: auto; }
  .row-actions .btn { max-width: none; }
}

/* App check-in done: emphasise the welcome */
.result p.welcome { font-size: calc(22px * var(--fs)); line-height: 1.6; color: var(--text); margin-top: 4px; }
.result p.welcome strong { color: var(--navy); font-weight: 700; }
.result p.welcome span { font-weight: 700; }

/* Part 2 camera flow */
.field input[readonly] { background: var(--soft); color: #374151; cursor: default; }
.field input.last4 { max-width: 160px; letter-spacing: 6px; font-size: calc(22px * var(--fs)); text-align: center; }
.queue-box.queue-inline { margin: 14px auto 0; }

/* Confirm dialog */
.dialog-backdrop { position: fixed; inset: 0; z-index: 50; background: rgba(15, 30, 70, .45); display: grid; place-items: center; padding: 20px; }
.dialog { width: 100%; max-width: 380px; background: #fff; border-radius: 20px; padding: 24px 20px 20px; box-shadow: 0 20px 50px rgba(0,0,0,.25); text-align: center; }
.dialog h3 { margin: 0 0 10px; color: var(--title); font-size: calc(22px * var(--fs)); }
.dialog-body p { margin: 0 0 8px; color: #374151; font-size: calc(18px * var(--fs)); line-height: 1.6; }
.dialog-body .dialog-strong { font-weight: 700; color: var(--text); letter-spacing: .5px; }
.dialog .row-actions { margin-top: 16px; }

/* ---------- Server-rendered pages (no inline styles: CSP style-src 'self') ---------- */
/* Background image (CDN base from configuration), drawn like the former inline background-image of .shell. */
.shell { position: relative; isolation: isolate; }
.shell-bg {
  position: absolute; inset: 0; z-index: -1; width: 100%; height: 100%;
  object-fit: cover; object-position: center top; pointer-events: none;
}

/* Former inline styles */
.calendar-error { margin-top: 14px; }
.page-title.detail-title { margin: 8px 0 10px; }

/* Calendar days are links (days with events) or plain text instead of buttons. */
a.day, span.day { display: flex; align-items: center; justify-content: center; text-decoration: none; }
a.icon-btn { text-decoration: none; }

/* Native <dialog open> as the backdrop: "ยกเลิก" closes it with method="dialog", no script. */
dialog.dialog-backdrop { border: 0; margin: 0; width: 100%; height: 100%; max-width: none; max-height: none; color: inherit; }
dialog.dialog-backdrop:not([open]) { display: none; }
.dialog .row-actions form { margin: 0; }
