/* ==========================================================================
   IAQ Inspection Platform — Design System
   ==========================================================================
   Stack: Django Templates + HTMX + minimal vanilla JS.
   No external runtime assets, no icon fonts, no animation libraries.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Primary palette: deep teal + fresh environmental green */
  --color-primary: #0d766e;
  --color-primary-hover: #0a5c56;
  --color-primary-light: #e6f4f3;

  --color-accent: #22a06b;
  --color-accent-hover: #1b8056;
  --color-accent-light: #e8f7ef;

  /* Neutrals */
  --color-bg: #f4f7f6;
  --color-surface: #ffffff;
  --color-elevated: #ffffff;
  --color-text: #1f3330;
  --color-text-heading: #142623;
  --color-muted: #5d7370;
  --color-border: #cdd6d4;
  --color-border-light: #e6ebe9;

  /* Semantics */
  --color-success: #16a34a;
  --color-success-bg: #dcfce7;
  --color-success-text: #14532d;
  --color-warning: #d97706;
  --color-warning-bg: #fef3c7;
  --color-warning-text: #78350f;
  --color-danger: #dc2626;
  --color-danger-hover: #b91c1c;
  --color-danger-bg: #fee2e2;
  --color-danger-text: #7f1d1d;
  --color-info: #0d766e;
  --color-info-bg: #e6f4f3;
  --color-info-text: #0a5c56;

  /* Spacing scale */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-8: 3rem;
  --space-10: 4rem;
  --space-12: 6rem;

  /* Typography scale */
  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-lg: 1.125rem;
  --text-xl: 1.25rem;
  --text-2xl: 1.5rem;
  --text-3xl: 2rem;
  --text-4xl: 2.5rem;

  /* Radius */
  --radius-sm: 0.375rem;
  --radius: 0.5rem;
  --radius-lg: 0.75rem;
  --radius-xl: 1rem;
  --radius-full: 9999px;

  /* Shadows */
  --shadow-sm: 0 1px 2px rgba(31, 51, 48, 0.06);
  --shadow: 0 1px 3px rgba(31, 51, 48, 0.1);
  --shadow-md: 0 4px 6px -1px rgba(31, 51, 48, 0.1), 0 2px 4px -2px rgba(31, 51, 48, 0.08);
  --shadow-lg: 0 10px 15px -3px rgba(31, 51, 48, 0.1), 0 4px 6px -4px rgba(31, 51, 48, 0.08);

  /* Layout */
  --header-height: 3.75rem;
  --max-content-width: 1150px;
  --max-landing-width: 1200px;
  --mobile-sticky-height: 3.25rem;

  /* A control's readable measure, not a frame width.  A long-form control that
     takes the whole row still has to read as prose, so it stops growing here
     instead of stretching across the panel.  Frame width lives in
     --max-content-width and nowhere else. */
  --field-measure: 46rem;

  /* Motion */
  --transition-fast: 150ms ease;
  --transition-base: 200ms ease;
}

.report-workspace,
.report-assessment-form,
.report-history-list {
    display: grid;
    gap: var(--space-4);
}

.report-generate-panel,
.report-history-card {
    padding: var(--space-4);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-md);
    background: var(--color-bg);
}

.report-history-card {
    display: grid;
    grid-template-columns: minmax(12rem, 1fr) auto auto;
    align-items: center;
    gap: var(--space-3);
}

@media (max-width: 700px) {
    .report-history-card {
        grid-template-columns: 1fr;
    }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* --------------------------------------------------------------------------
   Floor plans and percentage-based point markers
   -------------------------------------------------------------------------- */
.floorplan-upload-form { margin-bottom: var(--space-5); }
.floorplan-card-grid { display: grid; gap: var(--space-4); margin-top: var(--space-5); }
.floorplan-card { overflow: hidden; border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-surface); }
.floorplan-preview-link { display: block; background: var(--color-bg); text-align: center; }
/* The preview box shrink-wraps the image and is what the marker percentages
   resolve against, so the image and the drawings its markers were placed on are
   the same box: object-fit's letterboxing would leave the coordinates pinned to
   the container while the drawing shrank inside it. */
.floorplan-preview-box { position: relative; display: inline-block; max-width: 100%; }
.floorplan-preview { display: block; width: auto; max-width: 100%; max-height: 22rem; }
/* Non-interactive overlay tags on the case-page preview. Positions come from
   data attributes via app.js (CSP forbids a template inline style); they match
   the editor's own centre-anchored left/top semantics. */
.floorplan-preview-marker { position: absolute; left: 0; top: 0; transform: translate(-50%, -50%); padding: 1px 7px; border: 2px solid var(--color-surface); border-radius: var(--radius-full); background: rgba(13, 118, 110, 0.9); color: var(--color-surface); font-size: var(--text-xs); font-weight: 700; line-height: 1.4; white-space: nowrap; pointer-events: none; box-shadow: 0 0 0 1px rgba(23, 74, 69, 0.55); }
.floorplan-card-body { padding: var(--space-4); }
.floorplan-card-body h3 { margin-top: 0; }
.floorplan-meta { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-2) var(--space-4); }
.floorplan-meta div { min-width: 0; }
.floorplan-meta dt { color: var(--color-muted); font-size: var(--text-sm); }
.floorplan-meta dd { margin: 0; overflow-wrap: anywhere; }
.floorplan-editor-layout { display: grid; gap: var(--space-4); align-items: start; }
.floorplan-editor-main, .floorplan-point-panel { min-width: 0; }
.floorplan-canvas { position: relative; width: 100%; overflow: visible; border: 2px solid var(--color-border); border-radius: var(--radius); background: var(--color-bg); }
.floorplan-canvas:focus-visible { outline: 3px solid var(--color-accent); outline-offset: 3px; }
.floorplan-canvas.is-placing { cursor: crosshair; border-color: var(--color-accent); }
.floorplan-canvas > img { display: block; width: 100%; height: auto; }
.floorplan-marker { position: absolute; left: var(--marker-x, 0); top: var(--marker-y, 0); transform: translate(-50%, -50%); min-width: 56px; min-height: 56px; padding: var(--space-2); border: 3px solid var(--color-surface); border-radius: var(--radius-full); background: transparent; color: var(--color-surface); font-weight: 700; cursor: pointer; }
.floorplan-marker::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 2.25rem;
  height: 2.25rem;
  border-radius: var(--radius-full);
  background: var(--color-primary);
  box-shadow: var(--shadow-md);
  z-index: -1;
}
.floorplan-marker:hover::before, .floorplan-marker:focus-visible::before, .floorplan-marker.is-selected::before { background: var(--color-accent); outline: 3px solid var(--color-warning); outline-offset: 2px; }
.floorplan-marker.is-selected { z-index: 2; }
.floorplan-marker span { display: block; position: relative; z-index: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 8rem; padding: var(--space-1) var(--space-2); background: rgba(13, 118, 110, 0.85); border-radius: var(--radius-sm); }

@media (max-width: 430px) {
  .floorplan-marker { min-width: 64px; min-height: 64px; }
  .floorplan-marker::before { width: 2.75rem; height: 2.75rem; }
  .floorplan-marker span { font-size: var(--text-sm); }
}
.floorplan-point-list { display: grid; gap: var(--space-3); }
.floorplan-point-row { padding: var(--space-3); border: 1px solid var(--color-border); border-radius: var(--radius); }
.floorplan-point-row.is-marked { border-left: 4px solid var(--color-accent); }
.floorplan-point-row .actions { margin-top: var(--space-2); }

@media (min-width: 768px) {
  .floorplan-card-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .floorplan-editor-layout { grid-template-columns: minmax(0, 2fr) minmax(17rem, 1fr); }
  .floorplan-point-panel { position: sticky; top: calc(var(--header-height) + var(--space-4)); max-height: calc(100vh - var(--header-height) - var(--space-8)); overflow-y: auto; }
}

/* Electronic handwritten signature capture */
.signature-grid { display: grid; gap: var(--space-4); margin-bottom: var(--space-5); }
.signature-card { overflow: hidden; border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-surface); }
.signature-preview { display: block; width: 100%; height: 10rem; object-fit: contain; background: var(--color-surface); border-bottom: 1px solid var(--color-border-light); }
.signature-card-body, .signature-capture-card { padding: var(--space-4); }
.signature-card-body h3, .signature-capture-card h3 { margin-top: 0; }
.signature-valid { color: var(--color-success-text); background: var(--color-success-bg); }
.signature-stale { color: var(--color-warning-text); background: var(--color-warning-bg); }
.signature-legacy { color: var(--color-info-text); background: var(--color-info-bg); }
.signature-capture-card { border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-bg); }
.signature-canvas-wrap { width: 100%; overflow: hidden; border: 2px solid var(--color-border); border-radius: var(--radius); background: var(--color-surface); }
.signature-canvas { display: block; width: 100%; height: 220px; touch-action: none; cursor: crosshair; }

@media (max-width: 430px) {
  .signature-canvas { height: 180px; }
}

@media (min-width: 768px) and (max-width: 1024px) {
  .signature-canvas { height: 260px; }
}
.signature-canvas:focus-visible, .signature-canvas-wrap:focus-within { outline: 3px solid var(--color-primary); outline-offset: 2px; }
@media (min-width: 768px) { .signature-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* --------------------------------------------------------------------------
   Base
   -------------------------------------------------------------------------- */
* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: "Microsoft JhengHei", "PingFang TC", "Noto Sans TC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  background: var(--color-bg);
  color: var(--color-text);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  color: var(--color-primary);
  transition: color var(--transition-fast);
}

a:hover,
a:focus {
  color: var(--color-primary-hover);
}

img {
  max-width: 100%;
  height: auto;
}

:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* --------------------------------------------------------------------------
   Mobile sticky action bar
   -------------------------------------------------------------------------- */
.mobile-sticky-actions {
  display: none;
}

@media (max-width: 768px) {
  .mobile-sticky-actions {
    display: flex;
    position: sticky;
    bottom: 0;
    z-index: 45;
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    padding: var(--space-2) var(--space-3);
    gap: var(--space-2);
    box-shadow: 0 -2px 8px rgba(31, 51, 48, 0.08);
    margin: 0 calc(-1 * var(--space-3));
    align-items: center;
  }

  .mobile-sticky-actions__primary {
    flex: 1 1 auto;
    display: flex;
  }

  .mobile-sticky-actions__primary .btn {
    width: 100%;
    min-height: var(--mobile-sticky-height);
  }

  .mobile-sticky-actions__overflow {
    position: relative;
    flex: 0 0 auto;
  }

  .mobile-sticky-actions__overflow-menu {
    position: absolute;
    bottom: calc(100% + var(--space-2));
    right: 0;
    min-width: 12rem;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: var(--space-2);
    display: none;
    flex-direction: column;
    gap: var(--space-1);
  }

  .mobile-sticky-actions__overflow-menu.is-expanded {
    display: flex;
  }

  .mobile-sticky-actions__overflow-menu .btn {
    justify-content: flex-start;
    min-height: 40px;
  }

  /* Add bottom padding to main so sticky bar doesn't cover content */
  .mobile-sticky-actions + main,
  body:has(.mobile-sticky-actions) main {
    padding-bottom: calc(var(--space-8) + var(--mobile-sticky-height));
  }
}

/* --------------------------------------------------------------------------
   Layout containers
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--max-content-width);
  margin: 0 auto;
  padding: var(--space-4);
}

.container-narrow {
  max-width: 720px;
}

.page-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

@media (min-width: 768px) {
  .page-header {
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-start;
  }
}

.page-header__title {
  font-size: var(--text-2xl);
  margin: 0 0 var(--space-1);
}

.page-header__meta {
  color: var(--color-muted);
  font-size: var(--text-sm);
  margin: 0;
}

.page-header__actions {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}

.breadcrumbs {
  margin-bottom: var(--space-4);
}

.breadcrumbs__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.breadcrumbs__item:not(:last-child)::after {
  content: "/";
  margin-left: var(--space-1);
  color: var(--color-border);
}

.breadcrumbs__item a {
  color: var(--color-muted);
  text-decoration: none;
}

.breadcrumbs__item a:hover,
.breadcrumbs__item a:focus {
  color: var(--color-primary);
  text-decoration: underline;
}

.breadcrumbs__item--current {
  color: var(--color-text-heading);
  font-weight: 500;
}

main {
  min-height: calc(100vh - var(--header-height));
  padding-top: var(--space-5);
  padding-bottom: var(--space-8);
}

/* --------------------------------------------------------------------------
   Header / nav
   -------------------------------------------------------------------------- */
header {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
  position: sticky;
  top: 0;
  z-index: 50;
}

header nav {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  flex-wrap: wrap;
  min-height: var(--header-height);
}

header a.brand {
  font-weight: 700;
  color: var(--color-text-heading);
  text-decoration: none;
  font-size: var(--text-lg);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) 0;
}

header a.brand:hover,
header a.brand:focus {
  color: var(--color-primary);
}

header a.brand::before {
  content: "";
  display: inline-block;
  width: 1.5rem;
  height: 1.5rem;
  background: var(--color-primary);
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 20h16'/%3E%3Cpath d='M6 16l4-8 4 8'/%3E%3Cpath d='M8 12h4'/%3E%3Cpath d='M14 12l3-6 3 6'/%3E%3Cpath d='M16 8h2'/%3E%3C/svg%3E") no-repeat center;
  mask-size: contain;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 20h16'/%3E%3Cpath d='M6 16l4-8 4 8'/%3E%3Cpath d='M8 12h4'/%3E%3Cpath d='M14 12l3-6 3 6'/%3E%3Cpath d='M16 8h2'/%3E%3C/svg%3E") no-repeat center;
  -webkit-mask-size: contain;
}

header .nav-spacer {
  margin-left: auto;
}

header .nav-user {
  font-size: var(--text-sm);
  color: var(--color-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 12rem;
}
header .nav-actions {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-shrink: 0;
}

.brand__short { display: none; }

@media (max-width: 640px) {
  header nav {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    row-gap: var(--space-2);
    column-gap: var(--space-2);
    padding-top: var(--space-2);
    padding-bottom: var(--space-2);
  }

  header a.brand {
    grid-column: 1;
    grid-row: 1;
    padding: 0;
    min-width: 0;
  }

  .brand__full {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: var(--text-base);
  }

  header .nav-user {
    grid-column: 2;
    grid-row: 1;
    margin-left: auto;
    max-width: 11rem;
    text-align: right;
  }

  header .badge--uat {
    grid-column: 1 / -1;
    grid-row: 2;
    justify-self: start;
  }

  header .nav-actions {
    grid-column: 1 / -1;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: var(--space-2);
    width: 100%;
    flex-wrap: nowrap;
  }

  header .nav-actions .btn-sm {
    min-height: 38px;
    padding: var(--space-1) var(--space-3);
    white-space: nowrap;
    flex: 0 0 auto;
  }
}

@media (max-width: 365px) {
  header nav {
    column-gap: var(--space-1);
    row-gap: var(--space-2);
  }

  header .nav-user {
    max-width: 8rem;
  }

  header .nav-actions {
    gap: 6px;
  }

  header .nav-actions .btn-sm {
    padding: var(--space-1) 8px;
    font-size: var(--text-xs);
  }
}

/* --------------------------------------------------------------------------
   Typography
   -------------------------------------------------------------------------- */
h1, h2, h3, h4 {
  margin: var(--space-4) 0 var(--space-3);
  color: var(--color-text-heading);
  line-height: 1.3;
  font-weight: 700;
}

h1 {
  font-size: var(--text-2xl);
}

h2 {
  font-size: var(--text-xl);
}

h3 {
  font-size: var(--text-lg);
}

h4 {
  font-size: var(--text-base);
}

p {
  margin: var(--space-3) 0;
}

.text-muted {
  color: var(--color-muted);
}

.text-small {
  font-size: var(--text-sm);
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: var(--space-2) var(--space-4);
  border: 1px solid transparent;
  border-radius: var(--radius);
  background: var(--color-primary);
  color: #fff;
  text-decoration: none;
  font-size: var(--text-base);
  font-weight: 500;
  cursor: pointer;
  line-height: 1.2;
  transition: background var(--transition-fast), border-color var(--transition-fast), transform var(--transition-fast);
}

.btn:hover,
.btn:focus {
  background: var(--color-primary-hover);
  color: #fff;
}

.btn:active {
  transform: translateY(1px);
}

/* A disabled button has to look disabled. The native attribute and the
   aria-disabled convention are two spellings of the same state and share one
   declaration block, so they cannot drift apart. Before this covered
   `:disabled`, the signature confirm button was genuinely disabled -- and
   unsubmittable -- while still rendering in the full primary colour with a
   pointer cursor, which reads as pressable. */
.btn[aria-disabled="true"],
.btn[aria-disabled="true"]:hover,
.btn[aria-disabled="true"]:focus,
.btn:disabled,
.btn:disabled:hover,
.btn:disabled:focus {
  cursor: not-allowed;
  opacity: 0.65;
  background: var(--color-bg);
  color: var(--color-muted);
  border-color: var(--color-border);
}

.btn-secondary {
  background: var(--color-surface);
  color: var(--color-text);
  border-color: var(--color-border);
}

.btn-secondary:hover,
.btn-secondary:focus {
  background: var(--color-bg);
  color: var(--color-text-heading);
  border-color: var(--color-primary);
}

.btn-danger {
  background: var(--color-danger);
  border-color: var(--color-danger);
}

.btn-danger:hover,
.btn-danger:focus {
  background: var(--color-danger-hover);
  border-color: var(--color-danger-hover);
}

.btn-accent {
  background: var(--color-accent);
  border-color: var(--color-accent);
}

.btn-accent:hover,
.btn-accent:focus {
  background: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
}

.btn-warning {
  background: var(--color-warning);
  border-color: var(--color-warning);
  color: #fff;
}

.btn-warning:hover,
.btn-warning:focus {
  background: #b45309;
  border-color: #b45309;
  color: #fff;
}

.btn-ghost {
  background: transparent;
  color: var(--color-primary);
  border-color: transparent;
}

.btn-ghost:hover,
.btn-ghost:focus {
  background: var(--color-primary-light);
  color: var(--color-primary-hover);
  border-color: var(--color-primary-light);
}

.btn-sm {
  min-height: 36px;
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-sm);
}

.btn-lg {
  min-height: 52px;
  padding: var(--space-3) var(--space-6);
  font-size: var(--text-lg);
}

.btn-full {
  width: 100%;
}

/* --------------------------------------------------------------------------
   Cards & sections
   -------------------------------------------------------------------------- */
.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  margin-bottom: var(--space-4);
  box-shadow: var(--shadow-sm);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}

.card-title {
  font-size: var(--text-xl);
  font-weight: 700;
  margin: 0;
  color: var(--color-text-heading);
}

/* An account's display name may be empty, and the pages that name an account then
   print the email address instead -- which is one unbreakable token. At 360px a
   forty-character address is wider than the card, and without this it takes the whole
   document with it: the account deletion pages measured 447px wide in a 360px viewport
   before this rule.
   ``anywhere`` and not ``break-word`` so the long token also stops counting towards
   the card's intrinsic width, which is what keeps it from pushing a flex row wider
   than its parent. Ordinary text is unaffected: a break is only taken when there is
   nowhere else to go. */
.card-title,
.card .text-muted {
  overflow-wrap: anywhere;
}

.section-title {
  font-size: var(--text-2xl);
  font-weight: 700;
  margin: 0 0 var(--space-3);
  color: var(--color-text-heading);
}

.section-subtitle {
  color: var(--color-muted);
  margin: 0 0 var(--space-6);
}

.form-section {
  margin-bottom: var(--space-6);
}

/* --------------------------------------------------------------------------
   Forms
   -------------------------------------------------------------------------- */
.field {
  margin-bottom: var(--space-4);
}

.field label,
label.block {
  display: block;
  font-weight: 500;
  margin-bottom: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-text-heading);
}

.field input,
.field select,
.field textarea,
.field input[type="file"] {
  width: 100%;
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--text-base);
  background: var(--color-surface);
  color: var(--color-text);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.field textarea {
  min-height: 6rem;
  resize: vertical;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  border-color: var(--color-primary);
  outline: none;
  box-shadow: 0 0 0 3px rgba(13, 118, 110, 0.15);
}

.field .helptext,
.field .help,
.help-text {
  display: block;
  font-size: var(--text-sm);
  color: var(--color-muted);
  margin-top: var(--space-1);
}

.hint {
  display: inline-flex;
  font-size: var(--text-xs);
  font-weight: 500;
  margin-left: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  vertical-align: middle;
}

/* Requirement and optionality read as part of the label, never as a chip on a
   line of their own. `.field label` is a block, so a marker placed between the
   label and its control starts a new line and pushes that control down -- which
   is what left the controls of one row out of line with each other. These are
   inline, unpadded and background-free, so they add no height to anything. */
.required-indicator {
  color: var(--color-danger-text);
  font-weight: 600;
  margin-left: var(--space-1);
}

.optional-indicator {
  color: var(--color-muted);
  font-size: var(--text-xs);
  font-weight: 400;
}

/* One line per editable form, not one marker per field: the convention is
   stated once, where the form starts. */
.required-legend {
  font-size: var(--text-sm);
  color: var(--color-muted);
  margin: 0 0 var(--space-3);
}

.field ul.errorlist {
  color: var(--color-danger);
  font-size: var(--text-sm);
  margin: var(--space-1) 0 0;
  padding-left: var(--space-4);
}

.form-grid {
  display: grid;
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .form-grid.two {
    grid-template-columns: repeat(2, 1fr);
  }

  .form-grid.three {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (max-width: 430px) {
  .form-grid.three {
    gap: var(--space-3);
  }
}

@media (max-width: 600px) {
  .form-grid.mobile-single,
  .form-grid.two.mobile-single,
  .form-grid.three.mobile-single {
    grid-template-columns: 1fr;
  }
}

.radio-group {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
}

.radio-group label {
  font-weight: normal;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 44px;
  cursor: pointer;
}

.readonly-field {
  background: var(--color-bg);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  min-height: 44px;
  display: flex;
  align-items: center;
  color: var(--color-muted);
  border: 1px dashed var(--color-border);
}

.optional-hint {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-muted);
  margin-top: var(--space-1);
}

/* Optional master-data references on the inspection point form.  Collapsed by
   default: a floor is written, not chosen, and the catalogue is only relevant
   to a venue that keeps one. */
.point-master {
  margin-top: var(--space-2);
}

.point-master > summary {
  cursor: pointer;
  font-size: var(--text-sm);
  color: var(--color-muted);
  padding: var(--space-1) 0;
}

.point-master[open] > summary {
  margin-bottom: var(--space-2);
}

/* --------------------------------------------------------------------------
   Badges
   -------------------------------------------------------------------------- */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-border-light);
  color: var(--color-text);
  font-size: var(--text-sm);
  font-weight: 500;
  white-space: nowrap;
}

.badge.status-draft {
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
}

.badge.status-submitted {
  background: var(--color-info-bg);
  color: var(--color-info-text);
}

.badge.status-under_review {
  background: #e0e7ff;
  color: #3730a3;
}

.badge.status-returned {
  background: var(--color-danger-bg);
  color: var(--color-danger-text);
}

.badge.status-approved,
.badge.status-finalized {
  background: var(--color-success-bg);
  color: var(--color-success-text);
}

.badge.status-pending {
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
}

.badge--uat {
  background: var(--color-info-bg);
  color: var(--color-info-text);
  border: 1px solid var(--color-info-text);
}

.badge--warning {
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
}

.badge.loc-indoor {
  background: var(--color-primary-light);
  color: var(--color-primary);
}

.badge.loc-outdoor {
  background: var(--color-accent-light);
  color: var(--color-accent-hover);
}

/* --------------------------------------------------------------------------
   Workflow action bar + history
   -------------------------------------------------------------------------- */
.workflow-action-bar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: flex-end;
  margin-bottom: var(--space-4);
}

.workflow-action-bar .inline-form {
  display: inline-flex;
  gap: var(--space-2);
  align-items: flex-end;
}

.workflow-action-bar .return-form {
  flex: 1 1 320px;
}

.workflow-action-bar .return-form label {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  width: 100%;
}

.workflow-history-table {
  width: 100%;
  border-collapse: collapse;
}

.workflow-history-table th,
.workflow-history-table td {
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border-light);
  text-align: left;
  vertical-align: top;
}

.workflow-history-table th {
  font-weight: 600;
  color: var(--color-muted);
  font-size: var(--text-sm);
}

.workflow-history-table .workflow-arrow {
  margin: 0 var(--space-1);
  color: var(--color-muted);
}

.workflow-history-table .text-pre {
  white-space: pre-wrap;
}

/* --------------------------------------------------------------------------
   Lists (case / point / photo)
   -------------------------------------------------------------------------- */
.case-list,
.point-list,
.photo-list {
  display: grid;
  gap: var(--space-4);
}

.case-card,
.point-card,
.photo-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-base), border-color var(--transition-base);
}

.case-card:hover,
.point-card:hover,
.photo-card:hover {
  box-shadow: var(--shadow-md);
  border-color: var(--color-border);
}

.case-meta {
  display: grid;
  gap: var(--space-3);
}

.case-meta > div {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.case-meta .text-muted {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

@media (min-width: 768px) {
  .case-meta {
    grid-template-columns: 2fr 1fr 1fr 1fr;
    align-items: center;
  }

  .case-meta > div {
    display: block;
  }

  .case-meta .text-muted {
    display: block;
    margin-bottom: var(--space-1);
  }
}

.case-actions,
.point-actions,
.photo-actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-top: var(--space-3);
  align-items: center;
}

@media (min-width: 768px) {
  .case-actions,
  .point-actions,
  .photo-actions {
    margin-top: 0;
    justify-content: flex-end;
  }
}

.case-action--delete {
  display: inline-flex;
  align-items: center;
  padding: var(--space-1) var(--space-2);
  font-size: var(--text-sm);
  color: var(--color-danger);
  text-decoration: underline;
  border-radius: var(--radius);
  min-height: 32px;
}

.case-action--delete:hover,
.case-action--delete:focus {
  color: var(--color-danger-hover);
  background: var(--color-danger-bg);
}

.case-card {
  display: grid;
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .case-card {
    grid-template-columns: 1fr auto;
    align-items: center;
  }
}

.point-summary {
  display: grid;
  gap: var(--space-3);
}

@media (min-width: 768px) {
  .point-summary {
    grid-template-columns: 1fr 2fr 1.5fr 0.8fr 1fr;
    align-items: center;
  }
}

.measurement-form-wrapper {
  margin-top: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
}

.measurement-grid {
  display: grid;
  gap: var(--space-4);
}

.measurement-row {
  display: grid;
  gap: var(--space-2);
  align-items: center;
}

@media (min-width: 640px) {
  .measurement-row {
    grid-template-columns: 2fr 2fr 1fr;
  }
}

.measurement-row label {
  margin: 0;
}

.measurement-row input {
  width: 100%;
}

.measurement-row input[aria-invalid="true"] {
  border-color: var(--color-danger);
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.12);
}

.field-error {
  grid-column: 1 / -1;
  color: var(--color-danger);
  font-size: var(--text-sm);
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.field-error::before {
  content: "⚠";
  font-size: var(--text-sm);
}

/* 參考範圍 / 參考值 / 允許輸入範圍, and which formats the field takes. One muted line
   under the control, spanning the whole row so a long 允許輸入範圍 cannot push the
   unit out of its column or widen the grid on a phone. Muted, not warning-coloured:
   it is what the project expects, not a problem. */
.measurement-hint {
  grid-column: 1 / -1;
  display: block;
  color: var(--color-muted);
  font-size: var(--text-sm);
}

/* A reading that is on file and sits outside the range the project expects. Warning
   coloured, but never blocking -- the value is saved -- so it is drawn beside the
   error styling rather than instead of the value. ``flex-start`` and not ``center``:
   these sentences wrap to two lines at 360px, and a centred glyph would float beside
   neither of them. */
.field-warning {
  grid-column: 1 / -1;
  color: var(--color-warning-text);
  font-size: var(--text-sm);
  display: flex;
  align-items: flex-start;
  gap: var(--space-1);
}

.field-warning::before {
  content: "⚠";
  font-size: var(--text-sm);
  flex: none;
  line-height: inherit;
}

.unit {
  color: var(--color-muted);
  font-size: var(--text-sm);
}

.saved-indicator {
  color: var(--color-success);
  font-size: var(--text-sm);
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
}

.hidden {
  display: none !important;
}

/* --------------------------------------------------------------------------
   Photos
   -------------------------------------------------------------------------- */
.photo-card {
  display: grid;
  gap: var(--space-4);
  align-items: start;
}

@media (min-width: 768px) {
  .photo-card {
    grid-template-columns: auto 1fr auto;
    align-items: center;
  }
}

.photo-thumbnail {
  width: 120px;
  height: 120px;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--color-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--color-border);
}

.photo-thumbnail img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-meta {
  display: grid;
  gap: var(--space-1);
}

.photo-meta .text-muted {
  font-size: var(--text-sm);
}

/* --------------------------------------------------------------------------
   Messages / alerts
   -------------------------------------------------------------------------- */
.messages {
  margin-bottom: var(--space-4);
}

.alert {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius);
  background: var(--color-info-bg);
  color: var(--color-info-text);
  border: 1px solid rgba(13, 118, 110, 0.2);
  margin-bottom: var(--space-2);
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
}

.alert::before {
  content: "ℹ";
  font-weight: 700;
  flex-shrink: 0;
}

.alert.error {
  background: var(--color-danger-bg);
  color: var(--color-danger-text);
  border-color: rgba(220, 38, 38, 0.2);
}

.alert.error::before {
  content: "⚠";
}

.alert.success {
  background: var(--color-success-bg);
  color: var(--color-success-text);
  border-color: rgba(22, 163, 74, 0.2);
}

.alert.success::before {
  content: "✓";
}

.alert.warning {
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
  border-color: rgba(217, 119, 6, 0.2);
}

.alert.warning::before {
  content: "⚠";
}

/* --------------------------------------------------------------------------
   Pagination
   -------------------------------------------------------------------------- */
.pagination {
  display: flex;
  gap: var(--space-4);
  align-items: center;
  justify-content: center;
  margin-top: var(--space-6);
  flex-wrap: wrap;
}

.pagination .disabled {
  color: var(--color-muted);
  padding: var(--space-2) var(--space-3);
}

/* --------------------------------------------------------------------------
   Empty / utility
   -------------------------------------------------------------------------- */
.empty {
  color: var(--color-muted);
  padding: var(--space-5) 0;
  text-align: center;
  background: var(--color-surface);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-lg);
}

.actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  margin-top: var(--space-4);
}

/* The add-point control at the top of the point section. It leads the list
   rather than following it, so the space it needs is below it, not above. */
.actions--top {
  margin-top: 0;
  margin-bottom: var(--space-4);
}

.inline-form {
  display: inline;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   Landing page
   -------------------------------------------------------------------------- */
.landing-header {
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

.landing-header .container {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  min-height: var(--header-height);
}

.landing-hero {
  position: relative;
  overflow: hidden;
  background: linear-gradient(135deg, #eef7f6 0%, #f4f7f6 60%, #e8f7ef 100%);
  padding: var(--space-10) var(--space-4);
  text-align: center;
}

.landing-hero::before,
.landing-hero::after {
  content: "";
  position: absolute;
  pointer-events: none;
}

.landing-hero::before {
  top: -10%;
  right: -10%;
  width: 50%;
  height: 60%;
  background: radial-gradient(circle, rgba(13, 118, 110, 0.08) 0%, transparent 70%);
  animation: drift 24s ease-in-out infinite alternate;
}

.landing-hero::after {
  bottom: -10%;
  left: -10%;
  width: 40%;
  height: 50%;
  background: radial-gradient(circle, rgba(34, 160, 107, 0.08) 0%, transparent 70%);
  animation: drift 20s ease-in-out infinite alternate-reverse;
}

.landing-hero__content {
  position: relative;
  z-index: 2;
  max-width: var(--max-landing-width);
  margin: 0 auto;
}

.landing-hero__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-primary);
  background: var(--color-primary-light);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-full);
  margin-bottom: var(--space-5);
}

.landing-hero__title {
  font-size: clamp(1.75rem, 5vw, 3rem);
  line-height: 1.25;
  color: var(--color-text-heading);
  margin: 0 auto var(--space-5);
  max-width: 900px;
}

.landing-hero__subtitle {
  font-size: clamp(var(--text-base), 2vw, var(--text-lg));
  color: var(--color-muted);
  max-width: 680px;
  margin: 0 auto var(--space-6);
}

.landing-hero__cta {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.landing-hero__art {
  position: absolute;
  inset: 0;
  z-index: 1;
  opacity: 0.35;
  color: var(--color-primary);
}

.landing-hero__art svg {
  width: 100%;
  height: 100%;
}

@keyframes drift {
  from {
    transform: translate(0, 0);
  }
  to {
    transform: translate(2rem, 1.5rem);
  }
}

@media (prefers-reduced-motion: reduce) {
  .landing-hero::before,
  .landing-hero::after {
    animation: none;
  }
}

/* Landing sections */
.landing-section {
  padding: var(--space-10) var(--space-4);
}

.landing-section.alt {
  background: var(--color-surface);
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}

.landing-section .container {
  max-width: var(--max-landing-width);
}

.landing-section__header {
  text-align: center;
  max-width: 680px;
  margin: 0 auto var(--space-8);
}

.landing-section__title {
  font-size: var(--text-3xl);
  margin: 0 0 var(--space-3);
}

.landing-section__subtitle {
  color: var(--color-muted);
  margin: 0;
}

/* Value cards */
.value-grid,
.esg-grid {
  display: grid;
  gap: var(--space-5);
}

@media (min-width: 768px) {
  .value-grid,
  .esg-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

.value-card,
.esg-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--transition-base), transform var(--transition-base), border-color var(--transition-base);
}

.value-card:hover,
.esg-card:hover {
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
  border-color: var(--color-primary);
}

.value-card__icon,
.esg-card__icon {
  width: 3rem;
  height: 3rem;
  border-radius: var(--radius);
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: var(--space-4);
  background: var(--color-primary-light);
  color: var(--color-primary);
  font-size: var(--text-xl);
  font-weight: 700;
}

.value-card__title,
.esg-card__title {
  font-size: var(--text-xl);
  margin: 0 0 var(--space-2);
}

.value-card__text,
.esg-card__text {
  color: var(--color-muted);
  margin: 0;
}

/* Workflow stepper */
.workflow-stepper {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
}

.workflow-step {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text);
  font-weight: 500;
  box-shadow: var(--shadow-sm);
}

.workflow-step__num {
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--radius-full);
  background: var(--color-primary);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--text-sm);
  font-weight: 700;
  flex-shrink: 0;
}

.workflow-step.roadmap {
  border-style: dashed;
  background: var(--color-bg);
  color: var(--color-muted);
}

.workflow-step.roadmap .workflow-step__num {
  background: var(--color-muted);
}

.workflow-arrow {
  color: var(--color-muted);
  font-size: var(--text-xl);
  display: none;
}

@media (min-width: 768px) {
  .workflow-arrow {
    display: block;
  }
}

.roadmap-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin-left: var(--space-1);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-warning);
  background: var(--color-warning-bg);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
}

/* Footer */
.landing-footer {
  background: var(--color-text-heading);
  color: rgba(255, 255, 255, 0.8);
  padding: var(--space-8) var(--space-4);
  text-align: center;
}

.landing-footer .brand {
  color: #fff;
  font-weight: 700;
  font-size: var(--text-lg);
  text-decoration: none;
}

.landing-footer__copy {
  font-size: var(--text-sm);
  margin-top: var(--space-3);
  color: rgba(255, 255, 255, 0.6);
}

/* --------------------------------------------------------------------------
   Login page
   -------------------------------------------------------------------------- */
.login-layout {
  display: flex;
  min-height: calc(100vh - var(--header-height));
  align-items: center;
  justify-content: center;
  padding: var(--space-5);
  background: linear-gradient(135deg, var(--color-bg) 0%, var(--color-primary-light) 100%);
}

.login-card {
  width: 100%;
  max-width: 420px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  padding: var(--space-8);
  box-shadow: var(--shadow-lg);
}

.login-card__header {
  text-align: center;
  margin-bottom: var(--space-6);
}

.login-card__logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 3.5rem;
  height: 3.5rem;
  background: var(--color-primary);
  color: #fff;
  border-radius: var(--radius-lg);
  margin-bottom: var(--space-4);
  font-size: var(--text-2xl);
  font-weight: 700;
}

.login-card__title {
  font-size: var(--text-2xl);
  margin: 0 0 var(--space-1);
}

.login-card__subtitle {
  color: var(--color-muted);
  margin: 0;
}

/* --------------------------------------------------------------------------
   Responsive tables / scroll containers
   -------------------------------------------------------------------------- */
.table-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
}

.table-scroll table {
  width: 100%;
  min-width: min(100%, 640px);
  border-collapse: collapse;
}

@media (max-width: 600px) {
  .table-scroll table {
    min-width: 100%;
  }
}

/* 量測項目設定: five columns, four of them narrow codes and one a 中文 name.
   Letting it share the generic `.table-scroll table` rule crushes the name column
   to one character per line, which is not a table anyone can read. It scrolls
   instead -- the wrapper already does -- so the columns keep their own widths on a
   phone. Written against both classes so it wins on the generic rule. */
.table-scroll table.measurement-config-table {
  min-width: 34rem;
}

.table-scroll th,
.table-scroll td {
  padding: var(--space-3);
  text-align: left;
  border-bottom: 1px solid var(--color-border-light);
}

.table-scroll th {
  background: var(--color-bg);
  font-size: var(--text-sm);
  color: var(--color-text-heading);
  font-weight: 600;
}

/* --------------------------------------------------------------------------
   Snapshot section
   -------------------------------------------------------------------------- */
.snapshot-section {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  padding: var(--space-4);
  margin: var(--space-4) 0;
}

.snapshot-section .text-muted {
  font-size: var(--text-sm);
  margin-bottom: var(--space-4);
}

.snapshot-grid {
  display: grid;
  gap: var(--space-3);
}

@media (min-width: 640px) {
  .snapshot-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

.snapshot-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.snapshot-label {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-muted);
}

.snapshot-value {
  font-size: var(--text-base);
  color: var(--color-text);
}

.snapshot-value.muted-empty {
  color: var(--color-muted);
  font-style: italic;
}

/* --------------------------------------------------------------------------
   Checkbox list (inspectors)
   -------------------------------------------------------------------------- */
.checkbox-list {
  display: grid;
  gap: var(--space-2);
  grid-template-columns: 1fr;
}

@media (min-width: 640px) {
  .checkbox-list {
    grid-template-columns: repeat(2, 1fr);
  }
}

.checkbox-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}

.checkbox-item:hover,
.checkbox-item:focus-within {
  border-color: var(--color-primary);
  background: var(--color-primary-light);
}

.checkbox-item input[type="checkbox"] {
  width: 1.25rem;
  height: 1.25rem;
  accent-color: var(--color-primary);
  flex-shrink: 0;
}

.checkbox-item span {
  font-size: var(--text-base);
  color: var(--color-text);
}

/* Inspector option: name + role meta, vertically centered checkbox */
.checkbox-item.inspector-option {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  cursor: pointer;
  min-height: 56px;
  transition: border-color var(--transition-fast), background var(--transition-fast);
}

.checkbox-item.inspector-option:hover,
.checkbox-item.inspector-option:focus-within {
  border-color: var(--color-primary);
  background: var(--color-primary-light);
}

.inspector-option input[type="checkbox"] {
  width: 1.5rem;
  height: 1.5rem;
  accent-color: var(--color-primary);
  flex: 0 0 auto;
  margin: 0;
}

.inspector-option__content {
  display: flex;
  flex-direction: column;
  min-width: 0;
  line-height: 1.4;
}

.inspector-option__name {
  font-size: var(--text-base);
  font-weight: 500;
  color: var(--color-text);
}

.inspector-option__meta {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

@media (max-width: 430px) {
  .inspector-option input[type="checkbox"] {
    width: 1.75rem;
    height: 1.75rem;
  }

  .checkbox-item.inspector-option {
    padding: var(--space-3) var(--space-3);
    min-height: 64px;
  }
}

/* --------------------------------------------------------------------------
   Section navigation
   -------------------------------------------------------------------------- */
.section-nav {
  position: sticky;
  top: var(--header-height);
  z-index: 40;
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
  padding: var(--space-2) 0;
  margin-bottom: var(--space-4);
}

.section-nav__list {
  display: flex;
  gap: var(--space-1);
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  padding: var(--space-1);
  list-style: none;
  margin: 0;
}

.section-nav__item a {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-2) var(--space-3);
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: var(--color-text);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: 500;
  white-space: nowrap;
  min-height: 44px;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}

.section-nav__item a:hover,
.section-nav__item a:focus {
  background: var(--color-surface);
  border-color: var(--color-border);
  color: var(--color-primary);
}

.section-nav__item.is-active a {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

.section-nav__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.25rem;
  padding: 0 var(--space-1);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.2);
  font-size: var(--text-xs);
  font-weight: 700;
}

.section-nav__item.is-active .section-nav__count {
  background: rgba(255, 255, 255, 0.25);
  color: #fff;
}

/* A signature that exists but no longer matches the case data is flagged, not
   ticked — the ⚠ must not read as a completed section. */
.section-nav__count--warning {
  background: rgba(234, 179, 8, 0.25);
  color: var(--color-warning);
}

.section-nav__item.is-active .section-nav__count--warning {
  background: rgba(255, 255, 255, 0.25);
  color: #fff;
}

.section-nav--mobile {
  display: block;
  position: static;
  padding: 0 0 var(--space-2);
  border-bottom: none;
}

.section-nav--desktop {
  display: none;
}

@media (min-width: 768px) {
  .section-nav--mobile {
    display: none;
  }

  .section-nav--desktop {
    display: block;
  }
}

.section-nav__current {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--text-base);
  font-weight: 500;
  min-height: 44px;
  cursor: pointer;
}

.section-nav__current:hover,
.section-nav__current:focus {
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.section-nav__current-chevron {
  transition: transform var(--transition-fast);
}

.section-nav__current[aria-expanded="true"] .section-nav__current-chevron {
  transform: rotate(180deg);
}

.section-nav__dropdown {
  list-style: none;
  margin: var(--space-1) 0 0;
  padding: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  display: none;
  flex-direction: column;
  gap: var(--space-1);
}

.section-nav__dropdown.is-expanded {
  display: flex;
}

.section-nav__dropdown a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  color: var(--color-text);
  text-decoration: none;
  font-size: var(--text-base);
  min-height: 44px;
}

.section-nav__dropdown a:hover,
.section-nav__dropdown a:focus {
  background: var(--color-primary-light);
  color: var(--color-primary);
}

.section-panel {
  scroll-margin-top: calc(var(--header-height) + var(--space-10));
}

.js-collapsible.section-panel--hidden {
  display: none;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* --------------------------------------------------------------------------
   Print / high-contrast safe
   -------------------------------------------------------------------------- */
@media print {
  header,
  .actions,
  .case-actions,
  .point-actions,
  .photo-actions {
    display: none;
  }

  .card,
  .case-card,
  .point-card,
  .photo-card {
    box-shadow: none;
    border: 1px solid #999;
  }
}

.media-missing-notice {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  width: 100%;
  height: 100%;
  text-align: center;
  color: var(--color-muted);
  background: var(--color-bg);
  padding: var(--space-3);
}

.media-missing-notice__icon {
  font-size: var(--text-2xl);
  line-height: 1;
  opacity: 0.7;
}

.media-missing-notice__text {
  font-size: var(--text-sm);
  line-height: 1.4;
}

/* --------------------------------------------------------------------------
   Phase 4B.1 UI redesign additions
   -------------------------------------------------------------------------- */

/* Case header */
.case-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.case-header__main {
  min-width: 0;
}

.case-header__title {
  font-size: var(--text-2xl);
  margin: 0 0 var(--space-1);
}

.case-header__venue {
  font-size: var(--text-xl);
  font-weight: 600;
  color: var(--color-text-heading);
  margin-bottom: var(--space-1);
}

.case-header__meta {
  color: var(--color-muted);
  font-size: var(--text-sm);
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* Status Badges */
.case-header__status,
.review-actions__status {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-top: 2px;
  margin-bottom: 2px;
}

.status-description {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* Review actions card */
.case-header__actions,
.review-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  width: 100%;
  text-align: left;
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-sm);
  box-sizing: border-box;
}

.review-actions__title {
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-text-heading);
  letter-spacing: 0.02em;
}

.review-actions__approve {
  display: flex;
  justify-content: flex-start;
}

.review-actions__approve .btn {
  min-width: 96px;
}

.review-actions__submit .btn,
.review-actions__start-review .btn {
  min-width: 110px;
}

.review-actions__return {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border-light);
}

.return-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  width: 100%;
}

.return-form__group {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
}

.return-form__label {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text);
  margin: 0;
  text-align: left;
}

.return-form__textarea {
  width: 100%;
  min-height: 100px;
  padding: var(--space-2) var(--space-3);
  font-family: inherit;
  font-size: var(--text-sm);
  line-height: 1.5;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-bg);
  color: var(--color-text);
  resize: vertical;
  box-sizing: border-box;
}

.return-form__textarea:focus {
  outline: 2px solid var(--color-primary);
  outline-offset: -1px;
  border-color: var(--color-primary);
}

.return-form__actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 10px;
}

.return-form__actions .btn {
  min-width: 96px;
}

.case-header__back,
.review-actions__footer {
  display: flex;
  justify-content: flex-end;
  margin-top: 18px;
}

.review-actions__footer-standalone {
  display: flex;
  justify-content: flex-start;
  margin-top: var(--space-2);
}

@media (max-width: 768px) {
  .review-actions {
    max-width: 100%;
    padding: var(--space-3);
  }

  .review-actions__approve .btn,
  .review-actions__submit .btn,
  .review-actions__start-review .btn,
  .return-form__actions .btn,
  .review-actions__footer .btn {
    width: 100%;
  }

  .return-form__actions,
  .review-actions__footer {
    justify-content: stretch;
  }
}

/* --------------------------------------------------------------------------
   Case completion checklist
   -------------------------------------------------------------------------- */
.case-completion {
  margin-bottom: var(--space-4);
  padding: var(--space-4);
}

.case-completion__header {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--color-border-light);
}

@media (min-width: 768px) {
  .case-completion__header {
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
  }
}

.case-completion__title {
  font-size: var(--text-lg);
  margin: 0;
  color: var(--color-text-heading);
}

.case-completion__next-action {
  margin: 0;
  color: var(--color-primary);
  font-weight: 500;
  font-size: var(--text-sm);
}

.case-completion__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
}

@media (min-width: 768px) {
  .case-completion__list {
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-3);
  }
}

.case-completion__item {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  background: var(--color-bg);
  border: 1px solid var(--color-border-light);
}

.case-completion__item--complete {
  background: rgba(13, 148, 136, 0.08);
  border-color: rgba(13, 148, 136, 0.2);
}

.case-completion__item--incomplete {
  background: rgba(234, 179, 8, 0.08);
  border-color: rgba(234, 179, 8, 0.2);
}

.case-completion__icon {
  flex-shrink: 0;
  width: 1.25rem;
  text-align: center;
  font-weight: 700;
}

.case-completion__item--complete .case-completion__icon {
  color: var(--color-success);
}

.case-completion__item--incomplete .case-completion__icon {
  color: var(--color-warning);
}

.case-completion__label {
  flex: 1 1 auto;
  min-width: 0;
}

.case-completion__category {
  flex-shrink: 0;
  font-size: var(--text-xs);
  padding: 0.125rem 0.375rem;
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-muted);
  border: 1px solid var(--color-border-light);
}

.case-completion__detail {
  width: 100%;
  font-size: var(--text-xs);
  color: var(--color-muted);
  margin-top: var(--space-1);
}

.case-completion__note {
  margin: var(--space-3) 0 0;
  font-size: var(--text-xs);
  color: var(--color-muted);
}

/* Info groups (visual panels inside a card) */
.info-group {
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
  background: var(--color-surface);
}

.info-group__title {
  font-size: var(--text-lg);
  margin: 0 0 var(--space-3);
  color: var(--color-text-heading);
}

/* The chosen venue, read back as case data rather than as a control. One line
   of identity plus one line of context; the context line wraps rather than
   pushing the block past a narrow viewport. */
.selected-venue-summary {
  background: var(--color-bg);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  min-height: 44px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  overflow-wrap: anywhere;
}

.selected-venue-summary__name {
  font-weight: 700;
  color: var(--color-text-heading);
}

.selected-venue-summary__meta {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* Readonly value display */
.readonly-value {
  background: var(--color-bg);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  min-height: 44px;
  display: flex;
  align-items: center;
  color: var(--color-text);
  border: 1px dashed var(--color-border);
  flex-wrap: wrap;
}

.readonly-value--pre {
  white-space: pre-wrap;
  display: block;
  align-items: unset;
  padding: var(--space-3);
}

/* Section headers */
.section-header {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.section-header .card-title {
  margin: 0;
}

/* Point table */
.point-cards {
  display: grid;
  gap: var(--space-4);
}

.point-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  box-shadow: var(--shadow-sm);
}

.point-card__header {
  margin-bottom: var(--space-3);
}

.point-card__title {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  margin-bottom: var(--space-1);
}

.point-card__number {
  font-weight: 600;
  color: var(--color-muted);
}

.point-card__body {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.point-card__field {
  min-width: 0;
}

.point-card__field-label {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: var(--space-1);
}

.point-card__field-value {
  display: block;
  color: var(--color-text);
  word-break: break-word;
}

.point-card__actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.point-table-wrapper {
  display: none;
}

.point-table {
  width: 100%;
  min-width: 640px;
  border-collapse: collapse;
}

.point-table th,
.point-table td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border-light);
  text-align: left;
  vertical-align: top;
}

.point-table th {
  background: var(--color-bg);
  font-weight: 600;
  color: var(--color-text-heading);
  font-size: var(--text-sm);
}

.point-table tbody tr:hover {
  background: var(--color-bg);
}

.point-cell--number {
  font-weight: 600;
  color: var(--color-muted);
  white-space: nowrap;
}

.point-cell--actions {
  min-width: 15rem;
}

/* 編輯 / 量測值 / 刪除 are the most tapped controls on the case page, and at the
   --btn-sm height they sat well under the touch-target minimum. They are raised
   here rather than in .btn-sm itself, which other, denser lists rely on. Only
   the height changes: the buttons keep their padding and their row, so the
   desktop layout is unchanged apart from the taller row. */
.point-card__actions .btn,
.point-cell--actions .btn {
  min-height: 44px;
}

/* The measurement editor: one canonical region, outside both the mobile-card
   and desktop-table branches, so it is visible at every breakpoint. It is
   empty until a 量測值 button loads a point into it, and hidden while empty so
   the page does not carry a stray empty box. */
#measurement-editor {
  margin-top: var(--space-4);
  /* Where the region comes to rest when app.js brings it into view: the same
     clearance the section panels use for anchor navigation, so the sticky
     header never covers its heading. It belongs in CSS because scrollIntoView
     honours scroll-margin-top, and because the offset is a layout fact rather
     than something the script should hard-code. */
  scroll-margin-top: calc(var(--header-height) + var(--space-10));
}

#measurement-editor:empty {
  display: none;
}

#measurement-editor h4 {
  margin-top: 0;
}

@media (min-width: 768px) {
  .point-cards { display: none; }
  .point-table-wrapper { display: block; }
}

@media (max-width: 430px) {
  .point-card__body {
    grid-template-columns: 1fr;
  }
}

/* Empty state box */
.empty-state-box {
  text-align: center;
  padding: var(--space-8) var(--space-4);
  background: var(--color-bg);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-lg);
}

.empty-state-box__text {
  color: var(--color-muted);
  margin: 0 0 var(--space-4);
  font-size: var(--text-lg);
}

/* Photo gallery */
.photo-gallery {
  display: grid;
  gap: var(--space-4);
}

@media (min-width: 390px) {
  .photo-gallery {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 640px) {
  .photo-gallery {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 1024px) {
  .photo-gallery {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

.photo-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  display: flex;
  flex-direction: column;
}

.photo-card .photo-thumbnail {
  width: 100%;
  height: 10rem;
  border: 0;
  border-bottom: 1px solid var(--color-border-light);
  border-radius: 0;
}

.photo-card__body {
  padding: var(--space-3);
  flex: 1 1 auto;
}

.photo-card__category {
  margin-bottom: var(--space-1);
}

.photo-card__caption {
  margin-bottom: var(--space-1);
  word-break: break-word;
}

.photo-card__location {
  font-size: var(--text-sm);
}

.photo-card__meta {
  margin-top: var(--space-2);
}

.photo-card .photo-actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding: var(--space-3);
  border-top: 1px solid var(--color-border-light);
  margin-top: auto;
}

.photo-card .photo-actions .btn {
  min-height: 44px;
}

@media (max-width: 430px) {
  .photo-card .photo-actions .field {
    width: 100%;
    margin-bottom: var(--space-2);
  }

  .photo-card .photo-actions .btn {
    flex: 1 1 auto;
    min-height: 44px;
  }
}

.photo-upload-panel,
.floorplan-upload-panel,
.signature-capture-panel {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  margin-top: var(--space-3);
  background: var(--color-bg);
}

.photo-upload-panel.is-collapsed,
.floorplan-upload-panel.is-collapsed,
.signature-capture-panel.is-collapsed {
  display: none;
}

/* Floor plan marker status */
.floorplan-marker-status {
  margin: var(--space-3) 0;
}

/* Signature summary cards */
.signature-summary-grid {
  display: grid;
  gap: var(--space-4);
  margin-bottom: var(--space-5);
}

@media (min-width: 768px) {
  .signature-summary-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.signature-summary {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
}

.signature-summary__preview {
  height: 10rem;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border-light);
  display: flex;
  align-items: center;
  justify-content: center;
}

.signature-summary__preview img {
  max-height: 100%;
  max-width: 100%;
  object-fit: contain;
}

.signature-summary__body {
  padding: var(--space-4);
}

.signature-summary__body h3 {
  margin: 0 0 var(--space-1);
}

.signature-capture-panel h3 {
  margin-top: 0;
}

/* Workflow timeline */
.workflow-timeline {
  list-style: none;
  margin: 0;
  padding: 0;
  position: relative;
}

@media (min-width: 481px) {
  .workflow-timeline::before {
    content: "";
    position: absolute;
    left: 124px;
    top: 14px;
    bottom: 14px;
    width: 2px;
    background: var(--color-border);
    margin-left: 0;
    transform: translateX(-50%);
  }

  .workflow-timeline__item {
    display: grid;
    grid-template-columns: 110px 28px minmax(0, 1fr);
    padding: 12px 0;
    position: relative;
    align-items: start;
  }

  .workflow-timeline__item::before {
    content: "";
    position: absolute;
    left: 124px;
    top: 18px;
    width: 10px;
    height: 10px;
    border-radius: var(--radius-full);
    background: var(--color-primary);
    transform: translateX(-50%);
    z-index: 1;
  }

  .workflow-timeline__time {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    color: var(--color-muted);
    font-size: var(--text-sm);
    text-align: right;
    padding-right: 14px;
    line-height: 1.35;
  }

  .workflow-timeline__date {
    font-weight: 500;
    color: var(--color-text);
    white-space: nowrap;
  }

  .workflow-timeline__clock {
    font-size: var(--text-xs);
    white-space: nowrap;
  }

  .workflow-timeline__content {
    grid-column: 3;
    margin-left: 12px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: var(--space-3) var(--space-4);
  }
}

.workflow-timeline__action {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  margin-bottom: var(--space-2);
}

.workflow-timeline__actor,
.workflow-timeline__reason {
  font-size: var(--text-sm);
  margin-top: var(--space-1);
}

.workflow-timeline__reason {
  white-space: pre-wrap;
}

@media (max-width: 480px) {
  .workflow-timeline::before {
    left: 0.75rem;
    margin-left: 0;
  }

  .workflow-timeline__item {
    grid-template-columns: 1fr;
    gap: var(--space-2);
    padding-left: var(--space-6);
  }

  .workflow-timeline__item::before {
    left: 0.75rem;
  }

  .workflow-timeline__time {
    align-items: flex-start;
    text-align: left;
    flex-direction: row;
    gap: var(--space-2);
  }
}

@media (max-width: 430px) {
  .card {
    padding: var(--space-4);
  }

  .card-title {
    font-size: var(--text-lg);
  }

  .info-group {
    padding: var(--space-3);
  }

  .field input,
  .field select,
  .field textarea,
  .field input[type="file"] {
    font-size: 16px; /* prevent iOS zoom on focus */
  }
}

/* Case list filter bar */
.case-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
}

.case-filter__link {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: 500;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}

.case-filter__link:hover,
.case-filter__link:focus {
  background: var(--color-primary-light);
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.case-filter__link.is-active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

/* Case card redesign */
.case-card__body {
  min-width: 0;
}

.case-card__venue {
  font-size: var(--text-lg);
  font-weight: 700;
  margin: 0 0 var(--space-1);
  color: var(--color-text-heading);
}

.case-card__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  color: var(--color-muted);
  font-size: var(--text-sm);
  margin-bottom: var(--space-1);
}

.case-card__inspectors {
  font-size: var(--text-sm);
  color: var(--color-text);
  /* Names are joined into one run of text, and an email address is a single
     long token that cannot break on its own -- which pushed the whole card
     past the viewport at 360px. */
  overflow-wrap: anywhere;
}

.case-card__inspectors .text-muted {
  margin-right: var(--space-1);
}

/* Report workspace */
.report-panel {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  background: var(--color-surface);
}

.report-panel h3 {
  margin-top: 0;
}

.report-latest-card {
  display: grid;
  gap: var(--space-3);
  align-items: center;
  padding: var(--space-4);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  margin-bottom: var(--space-4);
}

@media (min-width: 768px) {
  .report-latest-card {
    grid-template-columns: 1fr auto auto;
  }
}

.report-latest-card .inline-actions,
.report-history-card .inline-actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.report-latest-card .inline-actions .btn,
.report-history-card .inline-actions .btn {
  min-height: 44px;
}

.status-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm);
  font-weight: 500;
}

.status-badge.status-valid {
  background: var(--color-success-bg);
  color: var(--color-success-text);
}

.status-badge.status-stale {
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
}

/* Utility */
.inline-actions {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   Report assessment subsection (現況與改善建議)
   Scoped single-column layout for the current-situation / improvement
   textareas. Overrides the shared .report-assessment-form grid rule so the
   fields stack vertically and the save button does not stretch to full width.
   -------------------------------------------------------------------------- */
.report-workspace {
  gap: var(--space-5);
}

/* Post-signature change history (audit trail) */

.badge.signature-changed {
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
  /* A chip is a word or two and stays on one line; this one is a sentence, and
     nowrap made it wider than the card it sits in -- which clips it, because the
     summary card hides its overflow. Let it wrap. */
  white-space: normal;
}

.badge.signature-warning {
  background: var(--color-danger-bg);
  color: var(--color-danger-text);
}

.signature-integrity {
  margin-top: var(--space-4);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border-light);
}

.signature-integrity__detail {
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.signature-integrity__subtitle {
  margin: var(--space-4) 0 var(--space-2);
  font-size: var(--text-sm);
}

/*
 * The change history keeps its columns at a readable width rather than being
 * squeezed to the panel: at 360 its min-content is still wider than the panel,
 * so the overflow is contained here instead of being pushed onto the page. No
 * min-width is declared -- the table's own content sets it.
 */
.signature-change-table-wrap {
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.signature-change-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--text-sm);
}

.signature-change-table th,
.signature-change-table td {
  border: 1px solid var(--color-border-light);
  padding: var(--space-1) var(--space-2);
  text-align: left;
  vertical-align: top;
  overflow-wrap: anywhere;
}

.signature-change-table .nowrap {
  white-space: nowrap;
}

/* Non-blocking report-readiness warnings: what the printed PDF will omit. */
.report-readiness-list {
  margin: var(--space-2) 0 0;
  padding-left: var(--space-5);
}

.report-workspace__divider {
  border: 0;
  border-top: 1px solid var(--color-border-light);
  margin: 0;
  width: 100%;
}

.report-panel--assessment {
  padding: var(--space-5);
}

.report-assessment-form {
  display: block;
  width: 100%;
  gap: 0;
}

.report-assessment-field {
  width: 100%;
}

.report-assessment-field + .report-assessment-field {
  margin-top: var(--space-5);
}

.report-assessment-field label {
  display: block;
  font-weight: 600;
  font-size: var(--text-base);
  color: var(--color-text-heading);
  margin: 0 0 var(--space-1);
}

.report-assessment-field .help-text {
  display: block;
  font-size: var(--text-sm);
  color: var(--color-muted);
  margin: 0 0 var(--space-2);
}

.report-assessment-field textarea {
  display: block;
  width: 100%;
  max-width: none;
  box-sizing: border-box;
  min-height: 200px;
  resize: vertical;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--text-base);
  line-height: 1.6;
  background: var(--color-surface);
  color: var(--color-text);
  transition: border-color var(--transition-fast), box-shadow var(--transition-fast);
}

@media (max-width: 430px) {
  .report-assessment-field textarea {
    min-height: 160px;
  }
}

.report-assessment-field textarea:focus {
  border-color: var(--color-primary);
  outline: none;
  box-shadow: 0 0 0 3px rgba(13, 118, 110, 0.15);
}

.report-assessment-field ul.errorlist {
  color: var(--color-danger);
  font-size: var(--text-sm);
  margin: var(--space-2) 0 0;
  padding-left: var(--space-4);
}

.report-assessment-actions {
  display: flex;
  justify-content: flex-start;
  margin-top: var(--space-5);
}

.report-assessment-actions .btn {
  width: auto;
  flex: 0 0 auto;
  align-self: flex-start;
}

.readonly-value--empty {
  color: var(--color-muted);
  font-style: italic;
}

@media (max-width: 600px) {
  .report-panel--assessment {
    padding: var(--space-4);
  }
}

/* --------------------------------------------------------------------------
   Management panel
   -------------------------------------------------------------------------- */
.mgmt-subnav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin: 0;
}

/* Navigation items, not actions.  Deliberately lighter than a button: the
   filled primary button on a page is that page's own action, and a row of
   button-shaped links next to it reads as a row of competing ones. */
.mgmt-subnav__link {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-muted);
  font-size: var(--text-sm);
  text-decoration: none;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.mgmt-subnav__link:hover,
.mgmt-subnav__link:focus-visible {
  background: var(--color-bg);
  color: var(--color-text-heading);
}

/* The current page.  Keyed off aria-current so the state assistive technology
   announces and the state the eye sees are the same attribute.  A tint rather
   than a fill, and no border, so it stays quieter than the primary action. */
.mgmt-subnav [aria-current="page"] {
  background: var(--color-primary-light);
  color: var(--color-primary);
  font-weight: 600;
}

/* Which project/client scope the current screen belongs to.  One line of the
   page header rather than a card of its own: the title, the identity, the
   actions and the navigation should read as one block, not four. */
.mgmt-context {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  align-items: flex-end;
  justify-content: space-between;
  margin: 0 0 var(--space-4);
}

.mgmt-context__eyebrow {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-muted);
}

.mgmt-context__scope {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: baseline;
  margin: var(--space-1) 0 0;
}

.mgmt-context__label {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.mgmt-context__value {
  font-size: var(--text-lg);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.mgmt-context__switch {
  flex-shrink: 0;
}
.mgmt-context__meta {
  margin: var(--space-1) 0 0;
  font-size: var(--text-sm);
  color: var(--color-muted);
}

/* Navigation grouped by altitude: project scope / platform catalog / accounts. */
.mgmt-nav {
  display: grid;
  gap: var(--space-2);
  margin: var(--space-3) 0 var(--space-4);
}

.mgmt-nav__group {
  display: grid;
  gap: var(--space-1);
}

/* Group label, not an operable element: the links below it are. */
.mgmt-nav__heading {
  margin: 0;
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--color-muted);
}

.mgmt-nav__note {
  margin: 0;
  font-size: var(--text-xs);
  color: var(--color-muted);
}

.mgmt-nav .mgmt-subnav {
  margin: 0;
}

.mgmt-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--space-4);
  margin-top: var(--space-4);
}

.mgmt-card {
  display: block;
  text-decoration: none;
  color: var(--color-text);
  padding: var(--space-4);
}

.mgmt-card:hover {
  border-color: var(--color-primary);
  box-shadow: var(--shadow-md);
}

.mgmt-card .card-title {
  margin: 0 0 var(--space-2);
}

.mgmt-count {
  font-size: var(--text-2xl);
  font-weight: 600;
  color: var(--color-primary);
  margin: 0;
}

/* Project status cards: the number is the information and the label is only
   its key, so the number outranks the title instead of the other way round. */
.mgmt-kpi .card-title {
  font-size: var(--text-base);
  font-weight: 500;
}

.mgmt-kpi .mgmt-count {
  font-size: var(--text-3xl);
  font-weight: 700;
}

/* Section heading with an optional action on the same line. */
.mgmt-section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.mgmt-section__head .mgmt-section__title {
  margin: 0;
}

.mgmt-card__desc {
  font-size: var(--text-sm);
  color: var(--color-muted);
  margin: var(--space-2) 0 0;
}

/* Management landing page: one actionable card per project/client. */
.mgmt-project-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.mgmt-project-card__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  justify-content: space-between;
}

.mgmt-project-card__head .card-title {
  margin: 0;
  overflow-wrap: anywhere;
}

.mgmt-project-card__meta {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.mgmt-project-card__cta {
  margin-top: auto;
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-primary);
}

.mgmt-project-card:hover .mgmt-project-card__cta,
.mgmt-project-card:focus-visible .mgmt-project-card__cta {
  text-decoration: underline;
}

.mgmt-project-card:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.mgmt-subtitle {
  color: var(--color-muted);
  margin: calc(-1 * var(--space-2)) 0 var(--space-4);
}

.mgmt-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: center;
  justify-content: space-between;
  margin: var(--space-4) 0;
}

.mgmt-filter {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

.mgmt-filter input[type="search"],
.mgmt-filter select {
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--text-sm);
  /* One height for the whole filter group: search, status and 篩選 line up. */
  min-height: 36px;
}

.mgmt-filter input[type="search"] {
  width: 14rem; /* wider than the status select, as the primary way in */
  max-width: 100%;
}

/* The management form frame.  The card carries no width of its own: it spans
   the panel's container exactly as the page title, the context header, the
   navigation groups and the tables around it do, so moving between management
   screens never moves the frame.  Density is decided by the field grid inside
   it — never by a per-page width — and a plain .card beside it is the same
   width for the same reason. */
.mgmt-form {
  padding: var(--space-5);
}

/* A long-form control is bounded by its own measure, not by the frame.  This
   caps what is typed into; it never caps what the card is. */
.mgmt-form .field textarea {
  max-width: var(--field-measure);
}

/* Below 430px the shared card rule tightens the inset.  .mgmt-form has to
   follow it rather than win by declaration order, or a management card and the
   plain card below it would disagree on their padding at every phone width. */
@media (max-width: 430px) {
  .mgmt-form {
    padding: var(--space-4);
  }
}

/* A long-form field may take the whole row.  It does so only where the row is
   otherwise complete, so the grid stays rectangular instead of opening a gap
   beside the field above it. */
.form-grid .field--wide {
  grid-column: 1 / -1;
}

/* System-generated values: stated, not offered as a missing control. */
.mgmt-info {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border-light);
}

.mgmt-info__title {
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-text-heading);
  margin: 0 0 var(--space-3);
}

.mgmt-info__key {
  display: block;
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text-heading);
  margin-bottom: var(--space-1);
}

.mgmt-info__code {
  max-width: 16rem;
  font-variant-numeric: tabular-nums;
}

/* Project/client create & edit separates its action row from the system-
   information block above it.  This is vertical rhythm for that one section,
   not a width: the card and the fields use the shared .mgmt-form frame. */
.project-form .actions {
  margin-top: var(--space-6);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border-light);
}

.mgmt-detail-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
  gap: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}

.mgmt-actions {
  white-space: nowrap;
}

.mgmt-actions .btn + .btn,
.mgmt-actions .inline-form + .btn,
.mgmt-actions .btn + .inline-form,
.mgmt-actions .inline-form + .inline-form {
  margin-left: var(--space-2);
}

/* Table row actions.  Four equally shaped buttons in one cell reads as four
   primary actions, so a row offers one compact button for the row's own
   action (編輯 / 檢視) and text actions for everything that is really
   navigation (案件 / 成員與角色) or a utility (產生設定密碼連結).  The cell
   stays a plain table cell — no flex, no width change — so the table keeps
   laying itself out exactly as before. */
.mgmt-row-actions {
  white-space: nowrap;
}

.mgmt-row-actions > * + * {
  margin-left: var(--space-2);
}

.mgmt-row-action {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 var(--space-2);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--color-primary);
  font-family: inherit;
  font-size: var(--text-sm);
  text-decoration: none;
  cursor: pointer;
  transition: background var(--transition-fast), color var(--transition-fast);
}

.mgmt-row-action:hover,
.mgmt-row-action:focus-visible {
  background: var(--color-primary-light);
  text-decoration: underline;
}

/* 永久刪除 sits in the same row as 編輯 and 案件, so it has to be told apart by more
   than position: colour, and a rule the eye catches before the click. It leads to a
   confirmation page -- nothing in the roster deletes -- but a dangerous door should
   look like one. */
.mgmt-row-action--danger {
  color: var(--color-danger);
}

.mgmt-row-action--danger:hover,
.mgmt-row-action--danger:focus-visible {
  background: var(--color-danger-bg);
}

/* An action this account may not take: 停用自己的帳號, 刪除最後一個系統管理員, 刪除一個
   already has history. Drawn rather than hidden, because "why can I not?" is answered
   by the title attribute and a vanished button answers nothing -- but drawn as text,
   not as something that invites a click. */
.mgmt-row-action--blocked {
  color: var(--color-muted);
  cursor: not-allowed;
  opacity: 0.75;
}

.mgmt-row-action--blocked:hover {
  background: none;
  text-decoration: none;
}

.user-table__self {
  color: var(--color-muted);
  font-size: var(--text-sm);
}

/* The delete-impact summary: one line per category, count on the right so the numbers
   form a column the eye can run down. */
.impact-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.impact-list__row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border-light);
}

.impact-list__row--blocking .impact-list__value {
  color: var(--color-danger);
  font-weight: 600;
}

.impact-list__value {
  font-variant-numeric: tabular-nums;
}

.impact-verdict {
  margin-top: var(--space-4);
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  font-weight: 600;
}

.impact-verdict--ok {
  background: var(--color-success-bg);
  color: var(--color-success-text);
}

.impact-verdict--blocked {
  background: var(--color-danger-bg);
  color: var(--color-danger-text);
}

/* User account roster.
   Phase 12J.2.1: five columns and two actions. It used to be seven columns and six
   actions -- the six included disabling, re-enabling, viewing a delete impact and
   deleting -- and those actions are why the table needed a horizontal scrollbar at
   every width, including on a desktop. The lifecycle moved to the account's own page,
   where the analysis behind it is cheap and where a refusal has room to explain
   itself; what is left here is an index.

   Column widths are min-widths, never fixed widths, and only the columns that must
   not break are held to one line: the account cell stacks a name and an address and
   lets the address wrap, which is what keeps the table inside the container at 1280px
   instead of overflowing it. */
.user-table__name,
.user-table__status,
.user-table__projects,
.user-table__login,
.user-table__actions {
  white-space: nowrap;
}

.user-table__name {
  display: block;
  font-weight: 500;
}

/* The address is identification, not identity: the person's name is the row's
   heading, so the email reads as secondary -- and it is the one value here that may
   be long and has nowhere to break, so it is the one allowed to wrap. */
.user-table__email {
  display: block;
  font-size: var(--text-sm);
  color: var(--color-muted);
  white-space: normal;
  overflow-wrap: anywhere;
}

.user-table__account {
  min-width: 11rem;
}

/* Two badges in one column: 啟用 / 停用 and 已設定 / 待設定密碼. They wrap rather
   than widen the column, because "待設定密碼" beside "啟用" is a column of its own
   that nothing else needed. */
.user-table__status {
  min-width: 6rem;
}

.user-table__status .badge + .badge {
  margin-left: var(--space-1);
}

/* A count, not a listing: the projects are named on the project's own screen, and a
   row here must not grow with how many projects an account is in. */
.user-table__projects {
  min-width: 4.5rem;
}

.user-table__login {
  min-width: 8.5rem; /* YYYY-MM-DD HH:MM */
}

/* The action column is the tightest one in the table, so its items sit closer
   together than the cell padding alone would put them. */
.user-table__actions > * + * {
  margin-left: var(--space-1);
}

/* Mobile-first, like the point list: a card per account, and the table takes over
   once there is room for it. A five-column table squeezed into 360px is smaller than
   anything anyone reads, and a table you scroll sideways to read is not a table. */
.user-cards {
  display: grid;
  gap: var(--space-4);
}

.user-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  box-shadow: var(--shadow-sm);
}

.user-card__head {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: space-between;
  align-items: flex-start;
}

.user-card__account {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.user-card__account strong {
  overflow-wrap: anywhere;
}

.user-card__email {
  color: var(--color-muted);
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}

.user-card__self {
  color: var(--color-muted);
  font-size: var(--text-sm);
}

.user-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.user-card__body {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-top: var(--space-3);
}

.user-card__field {
  display: flex;
  flex-direction: column;
}

.user-card__field-label {
  color: var(--color-muted);
  font-size: var(--text-sm);
}

.user-card__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.user-table-wrapper {
  display: none;
}

.user-table {
  width: 100%;
  min-width: 640px;
}

/* 960px, not the point list's 768px: a five-column table with these values needs about
   890px of content, so switching at 768 would hand a tablet a table it has to scroll
   sideways -- which is the thing this phase exists to remove, just moved from the
   desktop to the tablet. Below 960 every account is a card, and the table only appears
   where it fits. */
@media (min-width: 960px) {
  .user-cards { display: none; }
  .user-table-wrapper { display: block; }
}

/* Account edit page. The status line reads the same in 基本資料 and 帳號管理: a label
   and a badge, never a control -- the control has guards around it and lives in the
   section that explains it. */
.user-form__status {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
}

.user-form__status-label {
  color: var(--color-muted);
  font-size: var(--text-sm);
}

/* Why an account may not be disabled, or may not be deleted. Text rather than a
   greyed-out button: the sentence is the useful part, and a dead control says only
   that something is wrong somewhere. Warning-coloured and not danger-coloured -- being
   told you cannot do something is not itself an error. */
.lifecycle-blocked {
  flex-basis: 100%;
  margin: var(--space-2) 0 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
  font-size: var(--text-sm);
  overflow-wrap: anywhere;
}

/* 危險操作 is set apart from the cards above it, and no more than that: a red card
   shouting at somebody who came here to fix a display name is theatre. A rule along
   the top edge and the button's own danger styling carry it. */
.danger-zone {
  border-top: 3px solid var(--color-danger);
}

.danger-zone .card-title {
  color: var(--color-danger-text);
}

@media (max-width: 600px) {
  .mgmt-toolbar {
    flex-direction: column;
    align-items: stretch;
  }

  .mgmt-filter {
    flex-direction: column;
    align-items: stretch;
  }

  .mgmt-grid {
    grid-template-columns: 1fr;
  }

  .mgmt-actions {
    white-space: normal;
  }

  .mgmt-actions .btn + .btn,
  .mgmt-actions .inline-form + .btn,
  .mgmt-actions .btn + .inline-form,
  .mgmt-actions .inline-form + .inline-form {
    margin-left: 0;
    margin-top: var(--space-2);
  }

  .mgmt-actions form.inline-form {
    display: block;
  }
}

/* ==========================================================================
   Phase 7 — Case Management Dashboard
   ========================================================================== */

.case-dashboard {
  display: grid;
  gap: var(--space-4);
}

/* Summary cards */
.case-summary-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: var(--space-3);
}

.case-summary-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  text-decoration: none;
  color: var(--color-text);
  transition: background var(--transition-fast), border-color var(--transition-fast), box-shadow var(--transition-fast);
}

.case-summary-card:hover,
.case-summary-card:focus {
  background: var(--color-primary-light);
  border-color: var(--color-primary);
  box-shadow: var(--shadow-md);
}

.case-summary-card.is-active {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: #fff;
}

.case-summary-card__value {
  font-size: var(--text-2xl);
  font-weight: 700;
  line-height: 1.2;
}

.case-summary-card__label {
  font-size: var(--text-sm);
  margin-top: var(--space-1);
}

/* Quick queues */
.case-queues {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.case-queue-link {
  display: inline-flex;
  align-items: center;
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text);
  text-decoration: none;
  font-size: var(--text-sm);
  font-weight: 500;
  transition: background var(--transition-fast), border-color var(--transition-fast), color var(--transition-fast);
}

.case-queue-link:hover,
.case-queue-link:focus {
  background: var(--color-primary-light);
  border-color: var(--color-primary);
  color: var(--color-primary);
}

.case-queue-link.is-active {
  background: var(--color-warning-bg);
  border-color: var(--color-warning);
  color: var(--color-warning-text);
}

.case-queues__note {
  font-size: var(--text-sm);
  color: var(--color-muted);
  align-self: center;
}

/* Filter form */
.case-filter-panel {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
}

.case-filter-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.case-filter-form__basic,
.case-filter-form__advanced {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: 1fr;
}

.case-filter-form__advanced {
  display: none;
}

.case-filter-form__advanced.is-expanded {
  display: grid;
}

.case-filter-form__toggle {
  display: flex;
  align-items: flex-end;
}

.case-filter-form__advanced-toggle {
  width: 100%;
}

.case-filter-form__toggle-count {
  margin-left: var(--space-1);
}

@media (min-width: 768px) {
  .case-filter-form__basic {
    grid-template-columns: 2fr 1fr auto;
  }

  /* The panel stays a disclosure at every width. It used to be forced open on
     desktop with the toggle hidden, which left aria-expanded="false" describing
     a panel that was plainly visible -- and made 更多篩選 a mobile-only control
     for a panel that is the same panel everywhere. */
  .case-filter-form__advanced.is-expanded {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
  }

  .case-filter-form__actions {
    grid-column: span 2;
    justify-content: flex-end;
  }
}

@media (min-width: 1024px) {
  .case-filter-form__advanced.is-expanded {
    grid-template-columns: repeat(4, 1fr);
  }

  .case-filter-form__actions {
    grid-column: span 4;
  }
}

.case-filter-form__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.case-filter-form__field label {
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-muted);
}

.case-filter-form__field input,
.case-filter-form__field select {
  font-size: var(--text-base);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-bg);
  color: var(--color-text);
  width: 100%;
}

.case-filter-form__actions {
  display: flex;
  gap: var(--space-2);
  align-items: flex-end;
}

@media (min-width: 768px) {
  .case-filter-form {
    grid-template-columns: repeat(2, 1fr);
  }

  .case-filter-form__actions {
    grid-column: span 2;
    justify-content: flex-end;
  }
}

@media (min-width: 1024px) {
  .case-filter-form {
    grid-template-columns: repeat(4, 1fr);
  }

  .case-filter-form__actions {
    grid-column: span 4;
  }
}

/* Active filter chips */
.case-filter-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.case-filter-chips__title {
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.case-filter-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-full);
  background: var(--color-surface);
  color: var(--color-text);
  text-decoration: none;
  font-size: var(--text-sm);
  transition: background var(--transition-fast), border-color var(--transition-fast);
}

.case-filter-chip:hover,
.case-filter-chip:focus {
  background: var(--color-danger-bg);
  border-color: var(--color-danger);
  color: var(--color-danger-text);
}

.case-filter-chip--clear {
  border-style: dashed;
  color: var(--color-muted);
}

/* Case table (desktop) */
.case-table-wrapper {
  display: none;
  overflow-x: auto;
}

@media (min-width: 768px) {
  .case-table-wrapper {
    display: block;
  }
}

.case-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  font-size: var(--text-sm);
}

.case-table thead {
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-border);
}

.case-table th,
.case-table td {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  vertical-align: top;
}

.case-table th {
  font-weight: 600;
  color: var(--color-muted);
  white-space: nowrap;
}

.case-table tbody tr {
  border-bottom: 1px solid var(--color-border-light);
}

.case-table tbody tr:last-child {
  border-bottom: none;
}

.case-table__row--returned {
  background: var(--color-danger-bg);
}

.case-table__return-reason {
  margin: var(--space-1) 0 0;
  font-size: var(--text-xs);
  color: var(--color-danger-text);
}

/* Case table action column (desktop) */
.case-table th.case-table__th--actions,
.case-table td.case-table__td--actions {
  width: 120px;
  min-width: 120px;
  padding-left: var(--space-2);
  padding-right: var(--space-2);
}

.case-table__actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 100%;
}

.case-table__actions .case-table__action-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 30px;
  height: 30px;
  padding: 0 var(--space-2);
  font-size: var(--text-xs);
  border-radius: var(--radius);
  white-space: nowrap;
  box-sizing: border-box;
  text-decoration: none;
  font-weight: 500;
  line-height: 1;
}

.case-table__actions .case-action--delete {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 30px;
  height: 30px;
  padding: 0 var(--space-2);
  font-size: var(--text-xs);
  color: var(--color-danger);
  background: transparent;
  border: 1px solid var(--color-danger);
  border-radius: var(--radius);
  text-decoration: none;
  box-sizing: border-box;
  white-space: nowrap;
  cursor: pointer;
  font-weight: 500;
  line-height: 1;
  transition: background var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}

.case-table__actions .case-action--delete:hover,
.case-table__actions .case-action--delete:focus {
  background: var(--color-danger-bg);
  color: var(--color-danger-hover);
  border-color: var(--color-danger-hover);
}

.case-table__actions .case-table__action-status {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 24px;
  font-size: var(--text-xs);
  color: var(--color-muted);
  text-align: center;
  user-select: none;
  pointer-events: none;
}

/* Mobile card list (reuses existing .case-list / .case-card skeleton) */
.case-list {
  display: grid;
  gap: var(--space-4);
}

@media (min-width: 768px) {
  .case-list {
    display: none;
  }
}

.case-card__detail {
  font-size: var(--text-sm);
  color: var(--color-text);
  margin-top: var(--space-1);
}

.case-card__return-reason {
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
  color: var(--color-danger-text);
}

/* ==========================================================================
   Phase 9 — Report lifecycle and audit integration
   ========================================================================== */

.report-history {
  display: grid;
  gap: var(--space-4);
}

.report-history__header {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-3);
}

.report-history__title {
  font-size: var(--text-lg);
  font-weight: 600;
  margin: 0;
}

.report-history__list {
  display: grid;
  gap: var(--space-3);
}

.report-history-card {
  display: grid;
  gap: var(--space-3);
  padding: var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.report-history-card--current {
  border-left: 4px solid var(--color-primary);
}

.report-history-card__identity {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.report-history-card__version {
  font-weight: 600;
  color: var(--color-text-heading);
}

.report-history-card__meta {
  display: grid;
  gap: var(--space-1);
  font-size: var(--text-sm);
  color: var(--color-text);
}

.report-history-card__integrity {
  font-size: var(--text-sm);
}

.report-history-card__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

@media (min-width: 768px) {
  .report-history-card {
    grid-template-columns: 1fr auto;
    align-items: center;
  }

  .report-history-card__main {
    display: grid;
    gap: var(--space-2);
  }

  .report-history-card__meta {
    grid-template-columns: repeat(2, 1fr);
  }
}

.report-integrity {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-full);
  font-size: var(--text-sm);
  font-weight: 500;
}

.report-integrity--ok {
  background: var(--color-success-bg);
  color: var(--color-success-text);
}

.report-integrity--stale {
  background: var(--color-warning-bg);
  color: var(--color-warning-text);
}

.report-integrity--alert {
  background: var(--color-danger-bg);
  color: var(--color-danger-text);
}

/* Report detail / audit page */
.report-detail {
  display: grid;
  gap: var(--space-5);
}

.report-detail__status {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

.report-detail__section,
.report-detail__technical {
  padding: 20px 24px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
}

.report-detail__section-title {
  font-size: var(--text-lg);
  font-weight: 600;
  margin: 0 0 16px;
  color: var(--color-text-heading);
}

.report-detail__dl {
  display: grid;
  gap: 12px;
  margin: 0;
}

.report-detail__dl dt {
  font-size: var(--text-sm);
  color: var(--color-muted);
  font-weight: 500;
  line-height: 1.4;
  margin: 0;
}

.report-detail__dl dd {
  margin: 0;
  color: var(--color-text);
  line-height: 1.5;
}

.report-detail__hash {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0;
}

.report-hash-code {
  font-family: var(--font-mono, monospace);
  font-size: var(--text-sm);
  background: var(--color-bg);
  padding: 2px 8px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.report-hash-btn {
  flex-shrink: 0;
}

.report-detail__pre {
  white-space: pre-wrap;
  margin: 0;
  line-height: 1.6;
}

.report-detail__empty {
  color: var(--color-muted);
  margin: 0;
}

.report-detail__technical-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  cursor: pointer;
  list-style: none;
}

.report-detail__technical-summary::-webkit-details-marker {
  display: none;
}

.report-detail__technical-summary .report-detail__section-title {
  margin: 0;
}

.report-detail__technical-hint {
  font-size: var(--text-sm);
  color: var(--color-muted);
  flex-shrink: 0;
}

.report-detail__technical-body {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border-light);
}

.report-detail__technical-body .report-detail__section {
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 0;
  margin-bottom: var(--space-5);
}

.report-detail__technical-body .report-detail__section:last-child {
  margin-bottom: 0;
}

.report-detail__section-title--sub {
  font-size: var(--text-base);
  color: var(--color-text);
}

@media (min-width: 768px) {
  .report-detail__dl {
    grid-template-columns: 180px minmax(0, 1fr);
    column-gap: 20px;
    row-gap: 12px;
    align-items: center;
  }

  .report-detail__dl dt {
    text-align: left;
  }

  .report-detail__section--assessment .report-detail__dl {
    grid-template-columns: 240px minmax(0, 1fr);
    align-items: start;
  }

  .report-detail__section--assessment .report-detail__dl dt {
    white-space: nowrap;
    line-height: 1.6;
  }

  .report-detail__section--assessment .report-detail__pre {
    line-height: 1.6;
    margin: 0;
  }
}

@media (max-width: 767px) {
  .report-detail__hash {
    flex-wrap: wrap;
    gap: 8px;
  }
}

/* Workflow timeline improvements already scoped under .workflow-timeline-* */

/* --------------------------------------------------------------------------
   CSP-ready utility classes (replaces inline style attributes)
   -------------------------------------------------------------------------- */
.no-margin-top { margin-top: 0 !important; }
.error-page { text-align: center; padding: var(--space-10) 0; }
.mgmt-actions-spaced { margin-bottom: var(--space-4); }
.photo-caption-field { margin-bottom: 0; }
.offline-actions { justify-content: center; }

/* Offline page layout (replaces inline <style> block in offline.html) */
.offline-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  padding: var(--space-4);
}
.offline-card {
  max-width: 28rem;
  width: 100%;
  text-align: center;
}
.offline-card h1 { font-size: var(--text-xl); margin-bottom: var(--space-3); }
.offline-card p { color: var(--color-muted); }

/* Report PDF floorplan markers: position driven by CSS variables from template */
.report-marker {
  left: var(--marker-x, 0);
  top: var(--marker-y, 0);
}


/* --------------------------------------------------------------------------
   Phase 12F — venue structure, case-filter controls, guidance, submit bar
   -------------------------------------------------------------------------- */

/* Venue detail: the building → floor structure, listed in place.
   Optional reference data, so the empty state is stated as a complete state
   rather than as a gap to fill. */
.mgmt-toolbar__meta {
  color: var(--color-muted);
  font-size: var(--text-sm);
  margin-right: auto;
}
.venue-structure {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-3);
}
.venue-structure__building {
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  background: var(--color-surface);
  padding: var(--space-3);
}
.venue-structure__header {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.venue-structure__name {
  font-weight: 600;
  color: var(--color-text-heading);
}
.venue-structure__meta {
  color: var(--color-muted);
  font-size: var(--text-sm);
}
.venue-structure__actions {
  margin-left: auto;
  display: flex;
  gap: var(--space-2);
}
.venue-structure__floors {
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0 0 0 var(--space-4);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}
.venue-structure__floor {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  padding: var(--space-1) var(--space-2);
  background: var(--color-bg);
}
.venue-structure__floor-name {
  font-variant-numeric: tabular-nums;
}
.venue-structure__empty {
  margin: var(--space-3) 0 0;
  color: var(--color-muted);
  font-size: var(--text-sm);
}

/* Case page: the standing guidance above a section's content. Sits in the
   server-rendered section, not in the HTMX fragment that is swapped. */
.section-guidance {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-left: 3px solid var(--color-primary);
  border-radius: var(--radius-sm);
  background: var(--color-info-bg);
  color: var(--color-info-text);
  font-size: var(--text-sm);
}

/* Case filter: one height for every control, date inputs included.
   A native input[type="date"] resolves to its own intrinsic height on top of
   the shared padding, so it stood several pixels taller than the select beside
   it until the control had a value. The height is pinned rather than the
   appearance changed: the calendar button and the picker stay native. */
.case-filter-form__field input,
.case-filter-form__field select {
  height: 2.75rem;
  min-height: 2.75rem;
  line-height: 1.5;
  box-sizing: border-box;
}
.case-filter-form__field input[type="date"] {
  height: 2.75rem;
  min-height: 2.75rem;
  padding: var(--space-2) var(--space-3);
  line-height: 1.5;
}

/* Desktop: a submit action reachable from the bottom of a long case page.
   The header keeps its own 提交審核; this is the second and last copy, and it
   submits the same #case-submit-form. Mobile already has its own sticky bar,
   so neither renders at the other's width. */
.desktop-submit-bar {
  display: none;
}
@media (min-width: 768px) {
  .desktop-submit-bar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    position: sticky;
    bottom: 0;
    z-index: 44;
    margin-top: var(--space-5);
    padding: var(--space-2) var(--space-4);
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    box-shadow: 0 -2px 8px rgba(31, 51, 48, 0.08);
  }
  body:has(.desktop-submit-bar) main {
    padding-bottom: calc(var(--space-8) + 3.5rem);
  }
}
.desktop-submit-bar__state {
  display: flex;
  flex-direction: column;
  gap: 0.125rem;
  margin-right: auto;
  min-width: 0;
}
.desktop-submit-bar__status {
  font-weight: 600;
  color: var(--color-text-heading);
}
.desktop-submit-bar__note {
  color: var(--color-muted);
  font-size: var(--text-sm);
}

/* Account page: where an account belongs, read-only.
   The roles are listed here and changed in the project they belong to. */
.membership-summary {
  list-style: none;
  margin: 0 0 var(--space-3);
  padding: 0;
  display: grid;
  gap: var(--space-2);
}
.membership-summary__item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
}
.membership-summary__org {
  font-weight: 600;
  color: var(--color-text-heading);
}
.membership-summary__role {
  color: var(--color-muted);
}
.membership-summary__item .mgmt-row-action {
  margin-left: auto;
}

/* ======================================================================
   Phase 12F.1 — case workspace, media cards, guided flow

   The workspace stopped being one long form and became a set of stages:
   基本資料 reads back as a summary that opens into its form, 工作進度 says
   which stage is open and what comes next, and each section header carries
   its own title, count and action. Nothing below changes the meaning of a
   value or the rules about who may change one.
   ====================================================================== */

/* A section's action sits at the end of its header, on the line the title
   and count already occupy. It wraps below them on a narrow screen rather
   than squeezing the title, which is the one thing in the row that must
   stay readable. */
.section-header__action {
  margin-left: auto;
}

@media (max-width: 480px) {
  .section-header {
    flex-wrap: wrap;
  }
  .section-header .card-title {
    flex: 1 1 auto;
  }
  .section-header__action {
    margin-left: 0;
    width: 100%;
  }
}

.badge--muted {
  background: var(--color-bg);
  color: var(--color-muted);
  border: 1px solid var(--color-border-light);
}

/* --- 基本資料: the summary, and the toggle that opens the form ---------- */

.basic-summary__list {
  display: grid;
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
  padding: 0;
}

.basic-summary__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: baseline;
}

.basic-summary__label {
  flex: 0 0 auto;
  min-width: 6.5rem;
  color: var(--color-muted);
  font-size: var(--text-sm);
}

.basic-summary__value {
  margin: 0;
  flex: 1 1 12rem;
  min-width: 0;
  color: var(--color-text-heading);
  overflow-wrap: anywhere;
}

.basic-summary__details {
  border-top: 1px solid var(--color-border-light);
  padding-top: var(--space-3);
}

.basic-summary__details > summary {
  cursor: pointer;
  color: var(--color-primary);
  font-size: var(--text-sm);
  min-height: 44px;
  display: flex;
  align-items: center;
}

.basic-summary__details[open] > summary {
  margin-bottom: var(--space-3);
}

.basic-summary__details-body {
  display: grid;
  gap: var(--space-4);
}

/* One control, two labels: which one is readable is a function of the state
   the button already announces through aria-expanded, so the label cannot
   disagree with what the button does. */
.basic-edit-toggle__close {
  display: none;
}

[data-basic-edit-toggle][aria-expanded="true"] .basic-edit-toggle__open {
  display: none;
}

[data-basic-edit-toggle][aria-expanded="true"] .basic-edit-toggle__close {
  display: inline;
}

/* --- 工作進度 --------------------------------------------------------- */

.case-completion__item {
  display: block;
}

.case-completion__link {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  min-height: 44px;
  padding: var(--space-1) 0;
  color: inherit;
  text-decoration: none;
}

.case-completion__link:hover .case-completion__label,
.case-completion__link:focus-visible .case-completion__label {
  text-decoration: underline;
}

.case-completion__link:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.case-progress__points {
  margin: 0 0 var(--space-2) calc(var(--space-4) + var(--space-2));
}

.case-progress__point-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-1);
}

.case-progress__point {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  justify-content: space-between;
  font-size: var(--text-sm);
}

.case-progress__point-name {
  color: var(--color-text-heading);
}

.case-progress__point-state {
  color: var(--color-muted);
}

.case-progress__point--complete .case-progress__point-state {
  color: var(--color-success-text);
}

.case-progress__more {
  margin-top: var(--space-2);
  font-size: var(--text-sm);
}

.case-progress__more > summary {
  cursor: pointer;
  color: var(--color-primary);
  min-height: 44px;
  display: flex;
  align-items: center;
}

.case-progress__more-title {
  margin: var(--space-2) 0 var(--space-1);
  color: var(--color-text-heading);
  font-weight: 600;
}

.case-progress__more-list {
  margin: 0;
  padding-left: 1.25rem;
  color: var(--color-muted);
}

/* Inline confirmation after a section saves. Never a modal, and never a
   reason to move the page: the next step is offered as a link. */
.section-saved {
  margin: 0 0 var(--space-3);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius);
  background: var(--color-success-bg);
  color: var(--color-success-text);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

.section-saved a {
  color: inherit;
  font-weight: 600;
}

.section-guidance {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

.section-guidance__next {
  color: var(--color-text-heading);
}

/* --- 照片 cards ------------------------------------------------------- */

.photo-card__body {
  display: grid;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.photo-card__primary {
  display: grid;
  gap: var(--space-1);
}

.photo-card__location {
  font-weight: 600;
  color: var(--color-text-heading);
}

.photo-card__caption {
  margin: 0;
  overflow-wrap: anywhere;
}

.photo-card__secondary {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  color: var(--color-muted);
  font-size: var(--text-sm);
}

.photo-card__meta {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Caption on the left, delete at the far end: the destructive control keeps
   its distance from the text box a user is typing in. */
.photo-card__footer {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  align-items: flex-end;
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border-light);
}

.photo-caption-form {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: flex-end;
  flex: 1 1 16rem;
  min-width: 0;
}

.photo-caption-field {
  flex: 1 1 auto;
  min-width: 0;
}

.photo-caption-field__label {
  display: block;
  font-size: var(--text-xs);
  color: var(--color-muted);
  margin-bottom: var(--space-1);
}

.photo-caption-field input {
  width: 100%;
}

.photo-delete-form {
  margin-left: auto;
  flex: 0 0 auto;
}

@media (max-width: 480px) {
  .photo-delete-form {
    margin-left: 0;
    width: 100%;
  }
  .photo-delete-form .btn {
    width: 100%;
  }
}

/* --- 平面圖 card ------------------------------------------------------ */

.floorplan-meta__location {
  grid-column: 1 / -1;
}

.floorplan-meta__location dd {
  font-weight: 600;
  color: var(--color-text-heading);
}

.floorplan-card__actions {
  justify-content: flex-start;
}

.floorplan-card__actions .floorplan-delete-form {
  margin-left: auto;
}

@media (max-width: 480px) {
  .floorplan-card__actions .floorplan-delete-form {
    margin-left: 0;
    width: 100%;
  }
  .floorplan-card__actions .floorplan-delete-form .btn {
    width: 100%;
  }
}

/* The desktop action cell holds a div rather than being one, because an
   out-of-band refresh has to be parsed outside a table -- see point_actions.html.
   The layout therefore lives on the inner element. */
.point-cell--actions-inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

/* Phase 12F.1 follow-ups on the media cards.
   ------------------------------------------------------------------ */

/* One card per row on a phone, not two.

   The gallery went to two columns at 390px, which left each card about 150px
   wide -- enough for a thumbnail and a line of metadata, not for the caption
   editor the card now carries. A photo card at a phone width is one card. */
@media (min-width: 390px) and (max-width: 479px) {
  .photo-gallery {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* The caption and delete controls are tapped on a phone in the field, so they
   get the same 44px floor the point actions have. Only the height changes; the
   buttons keep their padding and their row. */
@media (max-width: 767px) {
  .photo-card__footer .btn,
  .floorplan-card__actions .btn {
    min-height: 44px;
  }
}

/* The media cards keep their caption and delete controls on screen; the print
   sheet hides them with every other action. .photo-actions is the class the old
   inline pair used and is kept in the list for any template still carrying it. */
@media print {
  .photo-actions,
  .photo-card__footer,
  .floorplan-card__actions {
    display: none;
  }
}

/* ---------------------------------------------------------------------------
 * Phase 12G signature requirements.
 *
 * The 電子簽名 section is driven by the form template's signature requirements:
 * one slot per requirement, each stating its label, whether it is required and
 * how many of how many are signed. Signature cards render inside their slot.
 * ------------------------------------------------------------------------- */
.signature-requirements__title {
  margin-bottom: var(--space-2);
}

.signature-slot-list {
  list-style: none;
  margin: 0 0 var(--space-5);
  padding: 0;
  display: grid;
  gap: var(--space-4);
}

.signature-slot {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4);
  background: var(--color-bg);
}

.signature-slot--done {
  border-color: var(--color-success, var(--color-border));
}

.signature-slot__header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.signature-slot__name {
  font-weight: 600;
}

.signature-summary-grid--slot {
  margin-top: var(--space-3);
  margin-bottom: 0;
}

.signature-extra {
  margin-bottom: var(--space-5);
}

.signature-extra > summary {
  cursor: pointer;
  font-weight: 600;
  padding: var(--space-2) 0;
}

.signature-tech {
  margin-top: var(--space-2);
}

.signature-tech > summary {
  cursor: pointer;
  font-size: var(--text-sm);
  color: var(--color-muted);
}

.signature-tech__list {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-1) var(--space-3);
  margin: var(--space-2) 0 0;
  font-size: var(--text-sm);
}

.signature-tech__list dt {
  color: var(--color-muted);
}

.signature-tech__list dd {
  margin: 0;
  overflow-wrap: anywhere;
}

.signature-change-disclosure > summary {
  cursor: pointer;
}

/* ---------------------------------------------------------------------------
 * Phase 12H permanent case deletion.
 *
 * The confirmation page states what will be removed before anything is, and
 * escalates from a plain list to a strong warning as the case's risk rises.
 * ------------------------------------------------------------------------- */
.delete-zone__headline {
  margin-bottom: var(--space-3);
  line-height: 1.5;
}

.delete-impact-list {
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border-light);
  border-radius: var(--radius-md, var(--radius-lg));
  display: grid;
  gap: var(--space-1);
}

.delete-impact-list li {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
}

.delete-impact-list__label {
  color: var(--color-muted);
}

.delete-impact-list__value {
  font-variant-numeric: tabular-nums;
}

.delete-warning {
  margin: var(--space-3) 0;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md, var(--radius-lg));
  background: var(--color-warning-bg, #fff7e6);
  border: 1px solid var(--color-warning-border, #ffd591);
  overflow-wrap: anywhere;
}

.delete-warning--strong {
  background: var(--color-danger-bg);
  border-color: var(--color-danger-border, currentColor);
  color: var(--color-danger-text);
  font-weight: 600;
}

.delete-warning--strong p {
  margin: 0 0 var(--space-1);
}

.delete-warning--strong p:last-child {
  margin-bottom: 0;
  font-weight: 400;
}

.delete-zone__irreversible {
  font-weight: 600;
  color: var(--color-danger-text);
}

.delete-zone__form .field {
  max-width: 32rem;
}
