* { box-sizing: border-box; }
html, body {
  margin: 0;
  padding: 0;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Hiragino Kaku Gothic ProN", "Yu Gothic", Meiryo, sans-serif;
  background: #fff;
  color: #222;
  font-size: 14px;
  /* Phase 5B: prevent any single element (wide table, banner with min-width,
   * etc.) from triggering page-level horizontal scroll on phones. Wide tables
   * still scroll inside their own .overflow-x:auto containers.
   *
   * Phase 5W: use `overflow-x: clip` instead of `hidden`. `hidden` creates
   * an implicit scroll container which BREAKS position:sticky on every
   * descendant — including the headers we just made sticky in Phase 5V.
   * `clip` simply clips overflowing content WITHOUT becoming a scroll
   * container, so position:sticky resolves against the viewport as
   * intended. Falls back to `hidden` on browsers that don't support clip. */
  overflow-x: hidden;
  overflow-x: clip;
  -webkit-text-size-adjust: 100%;
}
.hidden { display: none !important; }
.screen { min-height: 100vh; }

/* ===== Phase 5V: Sticky headers across all tiers =====
 * Keeps the user greeting / logout / nav controls always visible while
 * scrolling long tables. Applies to:
 *   - .app-header  (HQ / Agency / Admin)
 *   - .me-header   (Staff /me page)
 *   - .punch-header (timeclock page)
 * Each header MUST have a non-transparent background so content
 * underneath doesn't bleed through while scrolling.
 */
.app-header,
.me-header,
.punch-header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: #fff;
  backdrop-filter: saturate(180%) blur(4px);
  -webkit-backdrop-filter: saturate(180%) blur(4px);
}
/* Phase 5Y: when a scrollIntoView()/anchor lands on a section, leave
 * enough space above so the sticky header doesn't cover the section
 * heading. The browser respects scroll-margin-top on the target element
 * during programmatic scrolling. Also applies to document-level anchor
 * jumps so deep-linking (e.g. /me#payslip) lands properly. */
html { scroll-padding-top: 80px; }
.me-history-section,
.me-payslip-section,
.me-expense-section,
.admin-section,
.admin-page {
  scroll-margin-top: 80px;
}
@media (max-width: 640px) {
  html { scroll-padding-top: 70px; }
  .me-history-section,
  .me-payslip-section,
  .me-expense-section,
  .admin-section,
  .admin-page {
    scroll-margin-top: 70px;
  }
}
/* Print/PDF and screenshot exports should NOT have a sticky header
 * (it'd overlap the printable area on every page break). */
@media print {
  .app-header, .me-header, .punch-header { position: static !important; }
}

/* ===== Phase 5H: Fuloco brand mark =====
 * Reusable logo image classes. Always references /logo.svg so updating
 * the file replaces the logo everywhere on the site instantly. Keep the
 * SVG file at public/logo.svg.
 */
.brand-logo {
  display: inline-block;
  height: 36px;
  width: auto;
  vertical-align: middle;
  user-select: none;
  -webkit-user-drag: none;
}
.brand-logo-sm { height: 24px; }
.brand-logo-lg { height: 56px; }
.brand-logo-xl { height: 80px; }

/* Replace any text-based "Fuloco" heading with the logo. Used on the
 * login screens of all three tiers (business / agency / HQ).
 * Phase 5AD: bumped from 60px → 96px so the real logo is comfortably
 * visible at a glance. object-fit: contain prevents stretching even
 * if the source image has different aspect ratio than expected. */
.auth-card .auth-title-logo {
  display: block;
  margin: 0 auto 12px;
  height: 96px;
  max-width: 80%;
  object-fit: contain;
}
@media (max-width: 640px) {
  .auth-card .auth-title-logo { height: 78px; }
}

/* Sidebar brand area: small logo + (optional) "本部" / "代理店" label. */
.sidebar-brand-logo {
  height: 22px;
  width: auto;
  vertical-align: middle;
  filter: brightness(0) invert(1); /* invert to white on dark sidebar */
}

/* ---------- Mobile table overflow (Phase 4H/4I + 5B + 5D) ----------
 * Strategy: PC keeps natural table layout (no changes). On mobile we
 * convert wide tables to display:block + overflow-x:auto so they scroll
 * INSIDE the card instead of forcing the whole page wider than the
 * viewport. Combined with html/body overflow-x:hidden, the page itself
 * never scrolls horizontally on phones.
 *
 * Classes covered (mobile only):
 *   .hq-table, .ag-table, .payroll-table, .journal-table, .punch-table,
 *   .staff-settings-table, .special-table, .loco-table, .sales-table,
 *   .invoice-list-table, .inv-items-table, .hd-table, .summary-table
 *
 * Plus a JS safety net in /mobile-table-wrap.js wraps EVERY <table> in
 * a .mobile-scroll div so even tables without a recognised class get
 * scroll containers.
 */
@media (max-width: 900px) {
  .hq-table, .ag-table,
  .payroll-table, .journal-table, .punch-table,
  .staff-settings-table, .special-table,
  .loco-table, .sales-table,
  .invoice-list-table, .inv-items-table,
  .hd-table, .summary-table {
    display: block;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    max-width: 100%;
  }
  .hq-table { min-width: 720px; }
  .ag-table { min-width: 720px; }
  .payroll-table, .journal-table, .punch-table,
  .loco-table, .sales-table { min-width: 640px; }
  .invoice-list-table, .inv-items-table { min-width: 600px; }
  .hd-table { min-width: 480px; }
}

/* Phase 5D: JS-injected wrapper for any remaining <table> element.
 * The wrapper is a block-level div that constrains width to the
 * available container and provides horizontal scroll on overflow.
 * PC display is unaffected because we only show scroll bars when
 * content actually overflows. */
.mobile-scroll {
  width: 100%;
  max-width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  /* Visual cue on mobile: gradient shadow on the right edge that
   * signals "more content is hidden, swipe to see it". Only shown
   * when the wrapper is actually scrollable (handled by JS). */
  position: relative;
}
.mobile-scroll > table {
  /* Re-enforce default table behaviour inside the wrapper so column
   * widths size correctly and don't collapse. */
  border-collapse: inherit;
}

/* Scroll-hint shadow only visible on mobile-sized viewports. The
 * right-edge gradient fades out when the user scrolls all the way
 * to the right (via .mobile-scroll.scrolled-end class set by JS). */
@media (max-width: 900px) {
  .mobile-scroll.is-scrollable::after {
    content: "";
    position: absolute;
    top: 0;
    right: 0;
    width: 28px;
    height: 100%;
    pointer-events: none;
    background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(15,23,42,0.18) 100%);
    transition: opacity 0.2s;
    opacity: 1;
  }
  .mobile-scroll.is-scrollable.scrolled-end::after {
    opacity: 0;
  }
  .mobile-scroll.is-scrollable {
    /* Force a visible (chunky) scrollbar on iOS Safari mobile so users
     * realise the table scrolls. By default it auto-hides. */
    scrollbar-width: thin;
  }
  .mobile-scroll.is-scrollable::-webkit-scrollbar {
    height: 6px;
  }
  .mobile-scroll.is-scrollable::-webkit-scrollbar-thumb {
    background: rgba(15,23,42,0.35);
    border-radius: 3px;
  }
  /* Small hint label above scrollable tables. Only shown on mobile
   * and only when the table actually scrolls. */
  .mobile-scroll.is-scrollable::before {
    content: "← 左右にスワイプして全列を表示 →";
    display: block;
    padding: 6px 10px;
    font-size: 11px;
    color: #64748b;
    background: #f1f5f9;
    border-radius: 4px;
    margin-bottom: 6px;
    text-align: center;
    font-family: inherit;
  }
}

/* ===== Phase 5F: Mobile card layout =====
 *
 * On phones (<= 640px) we convert every wrapped table into a stacked
 * "card list": each row becomes a card, each cell becomes a
 *   [label]: [value]
 * pair (the label comes from the matching <th> via data-label,
 * injected by mobile-table-wrap.js). This eliminates the need for
 * horizontal scrolling entirely on mobile.
 *
 * PC (>900px) and tablets (641-900px) keep the normal table layout
 * with the overflow-x:auto fallback from Phase 4H/4I/5D.
 *
 * Conditions for the card layout to apply:
 *   - viewport <= 640px
 *   - the <table> is inside .mobile-scroll (i.e. wrapped by the JS
 *     safety net, which is loaded on portal pages)
 */
@media (max-width: 640px) {
  .mobile-scroll {
    overflow-x: visible !important;
  }
  .mobile-scroll > table {
    display: block !important;
    width: 100% !important;
    min-width: 0 !important;
    border-collapse: separate;
    border-spacing: 0;
    background: transparent !important;
  }
  .mobile-scroll > table > thead {
    display: none !important;
  }
  /* Phase 5K: horizontal label:value rows, single column per card.
   *   - Each <td> is one ROW inside the card
   *   - Label sits on the LEFT (75px slot), value on the RIGHT
   *   - Tight vertical spacing so a whole record fits on one screen
   *   - PC layout (>640px) is unaffected — these rules live inside
   *     @media (max-width: 640px) */
  .mobile-scroll > table > tbody {
    display: block;
  }
  .mobile-scroll > table > tbody > tr {
    display: block;
    border: 1px solid #e2e8f0;
    border-radius: 10px;
    padding: 8px 12px;
    margin: 0 0 8px 0;
    background: #fff;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
    width: auto !important;
    max-width: 100% !important;
  }
  /* Each labeled cell becomes one horizontal "label : value" row. */
  .mobile-scroll > table > tbody > tr > td[data-label]:not([data-label=""]) {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    gap: 10px;
    border: none !important;
    padding: 2px 0 !important;
    margin: 0 !important;
    text-align: left !important;
    background: transparent !important;
    word-break: break-word;
    min-width: 0;
    font-size: 13.5px;
    line-height: 1.55;
  }
  .mobile-scroll > table > tbody > tr > td[data-label]:not([data-label=""])::before {
    content: attr(data-label);
    color: #64748b;
    font-size: 12px;
    font-weight: 500;
    flex: 0 0 75px;
    text-align: left;
    line-height: 1.55;
    /* Allow very long labels to wrap inside the 75px slot rather
     * than overflowing or pushing the value right. */
    white-space: normal;
    word-break: keep-all;
  }
  /* Action / button cells (no <th> label): full width, with a soft
   * separator above so it visually closes the card. */
  .mobile-scroll > table > tbody > tr > td:not([data-label]),
  .mobile-scroll > table > tbody > tr > td[data-label=""] {
    display: block;
    border: none !important;
    padding: 6px 0 2px !important;
    margin-top: 5px;
    text-align: left !important;
    background: transparent !important;
    border-top: 1px dashed #eef2f6;
  }
  .mobile-scroll > table > tbody > tr > td:not([data-label]) > button,
  .mobile-scroll > table > tbody > tr > td[data-label=""] > button {
    display: inline-block;
    margin: 2px 4px 2px 0;
    padding: 5px 12px;
    font-size: 12px;
    width: auto;
    vertical-align: middle;
  }
  .mobile-scroll > table > tbody > tr > td:not([data-label]) > a,
  .mobile-scroll > table > tbody > tr > td[data-label=""] > a {
    display: inline-block;
    margin: 2px 4px 2px 0;
    vertical-align: middle;
  }
  /* Empty-state placeholders */
  .mobile-scroll > table > tbody > tr > td[colspan]:not([colspan="1"]) {
    display: block !important;
    text-align: center !important;
    color: #94a3b8;
    padding: 12px 0 !important;
    border: none !important;
  }
  .mobile-scroll > table > tbody > tr > td[colspan]:not([colspan="1"])::before {
    display: none;
  }
  /* Hide the scroll hint banner/gradient since no scrolling is needed. */
  .mobile-scroll.is-scrollable::before,
  .mobile-scroll.is-scrollable::after {
    display: none !important;
  }

  /* ===== 合計 (tfoot) row as a labeled card on phones =====
   * On desktop the tfoot is a single brand-colored total bar. On phones
   * the data rows above are stacked label:value cards, so an unlabeled
   * horizontal total bar is unreadable (you can't tell which figure is
   * which column). Mirror the tbody card treatment: a card titled 合計
   * with one "label : value" row per column.
   * Shared by the 売上表 (.sales-table) and 給与計算補助 (.payroll-table). */
  .mobile-scroll > table.sales-table > tfoot,
  .mobile-scroll > table.payroll-table > tfoot {
    display: block;
  }
  .mobile-scroll > table.sales-table > tfoot > tr,
  .mobile-scroll > table.payroll-table > tfoot > tr {
    display: block;
    border: 1px solid #1f4f5b;
    border-radius: 10px;
    padding: 8px 12px;
    margin: 0 0 8px 0;
    background: #f2f7f8;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
  }
  .mobile-scroll > table.sales-table > tfoot > tr > td.sales-foot-title,
  .mobile-scroll > table.payroll-table > tfoot > tr > td.payroll-foot-title {
    display: block;
    border: none !important;
    background: transparent !important;
    color: #1f4f5b !important;
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.06em;
    text-align: left !important;
    padding: 0 0 6px !important;
    margin-bottom: 4px;
    border-bottom: 1px solid #d5e1e4 !important;
  }
  .mobile-scroll > table.sales-table > tfoot > tr > td[data-label]:not([data-label=""]),
  .mobile-scroll > table.payroll-table > tfoot > tr > td[data-label]:not([data-label=""]) {
    display: flex;
    flex-direction: row;
    align-items: baseline;
    gap: 10px;
    border: none !important;
    padding: 2px 0 !important;
    margin: 0 !important;
    text-align: left !important;
    background: transparent !important;
    color: #0f172a !important;
    font-weight: 600;
    font-size: 13.5px;
    line-height: 1.55;
    min-width: 0;
  }
  .mobile-scroll > table.sales-table > tfoot > tr > td[data-label]:not([data-label=""])::before,
  .mobile-scroll > table.payroll-table > tfoot > tr > td[data-label]:not([data-label=""])::before {
    content: attr(data-label);
    color: #64748b;
    font-size: 12px;
    font-weight: 500;
    flex: 0 0 75px;
    text-align: left;
    white-space: normal;
    word-break: keep-all;
  }
  .mobile-scroll > table.sales-table > tfoot > tr > td.col-hidden,
  .mobile-scroll > table.payroll-table > tfoot > tr > td:not([data-label]):not(.payroll-foot-title) {
    display: none !important;
  }
  /* 売上表カード: 各支払方法（レジ10%/カード/paypay…）の行に薄い区切り線を
     入れて、どの項目の値かひと目で分かるようにする。日セルと最終行は除く。 */
  .mobile-scroll > table.sales-table > tbody > tr > td[data-label]:not([data-label=""]) {
    border-bottom: 1px solid #eef2f6 !important;
    padding: 5px 0 !important;
  }
  .mobile-scroll > table.sales-table > tbody > tr > td[data-label]:not([data-label=""]):last-child {
    border-bottom: none !important;
  }

  /* ===== Phase 5AQ: stack action-heavy cells on mobile =====
   * The "従業員アカウント" cell on the staff settings page packs in a
   * status badge + パスワード再発行 button + 取消 button + a
   * 「店舗共有用オプション」<details> disclosure. The default mobile
   * card layout (label : value side by side, 75px label slot) squeezed
   * all of that into ~200px and the buttons started breaking text
   * character-by-character.
   *
   * Specific override: .acct-cell drops the flex row, puts the label
   * on top, lets the buttons wrap naturally with their own min-width.
   * Same treatment for any 6th-column action cell with multiple
   * buttons (保存 / 詳細). */
  .mobile-scroll > table > tbody > tr > td.acct-cell[data-label]:not([data-label=""]),
  .mobile-scroll > table > tbody > tr > td.acct-cell {
    display: block !important;
    border-top: 1px dashed #eef2f6 !important;
    padding: 8px 0 4px !important;
    margin-top: 4px !important;
  }
  .mobile-scroll > table > tbody > tr > td.acct-cell[data-label]:not([data-label=""])::before {
    display: block;
    content: attr(data-label);
    color: #64748b;
    font-size: 12px;
    font-weight: 500;
    margin-bottom: 6px;
    line-height: 1.4;
    flex: none !important;
  }
  .mobile-scroll > table > tbody > tr > td.acct-cell button {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    min-width: 0;
    width: auto !important;
    white-space: nowrap !important;
    word-break: keep-all !important;
    margin: 2px 4px 2px 0;
    padding: 6px 12px;
    font-size: 12.5px;
    line-height: 1.3;
  }
  .mobile-scroll > table > tbody > tr > td.acct-cell .acct-status-ok,
  .mobile-scroll > table > tbody > tr > td.acct-cell .acct-status-none {
    margin-right: 6px;
    white-space: nowrap;
  }
  .mobile-scroll > table > tbody > tr > td.acct-cell details {
    width: 100%;
    margin-top: 8px;
  }
  .mobile-scroll > table > tbody > tr > td.acct-cell details summary {
    padding: 4px 0;
    white-space: nowrap;
  }
  .mobile-scroll > table > tbody > tr > td.acct-cell details > div {
    width: auto !important;
  }
  /* Also fix the row-action cell (保存 / 詳細) so it doesn't squeeze. */
  .staff-settings-table .mobile-scroll > table > tbody > tr > td:last-child,
  .mobile-scroll > table.staff-settings-table > tbody > tr > td:last-child {
    text-align: left !important;
  }

  /* ===== Phase 5J: compact header for prev/next-month bars =====
   * Across admin/me/punch/shift-request, the page header has
   * [prev-month] [month-title] [next-month] + bell + logout. On phones
   * these buttons were inheriting desktop padding (8px 14px) which made
   * each button consume ~40% of the viewport width and pushed the
   * month-title off the right edge. */
  .app-header {
    padding: 8px 10px !important;
    gap: 6px !important;
  }
  .app-header .header-left {
    flex-wrap: wrap;
    gap: 6px;
    min-width: 0;
  }
  .app-header .header-right {
    gap: 6px !important;
  }
  .app-header .btn,
  .header-left .btn,
  .header-right .btn {
    padding: 5px 10px !important;
    font-size: 12px !important;
    border-radius: 6px;
  }
  .month-title {
    font-size: 16px !important;
    margin: 0 4px !important;
    flex: 0 1 auto;
  }
  /* Sidebar toggle (hamburger) and notification bell can sit next to
   * each other without ballooning. */
  #fx-sidebar-toggle, .sidebar-toggle {
    padding: 4px 8px !important;
    font-size: 18px !important;
  }

  /* Punch page header */
  .punch-header {
    flex-wrap: wrap !important;
    gap: 8px !important;
    padding: 12px 14px !important;
    align-items: center !important;
  }
  .punch-header > * { min-width: 0; }
  .punch-header > div:first-child { flex: 1 1 auto; min-width: 0; }
  .punch-title { font-size: 18px !important; white-space: nowrap; }
  .punch-date { font-size: 11px !important; white-space: nowrap; }
  .punch-clock { font-size: 26px !important; letter-spacing: 1px !important; flex: 0 0 auto; }
  .punch-grid { grid-template-columns: 1fr !important; padding: 12px 8px !important; gap: 10px !important; }

  /* Mobile-friendly modal sizing */
  .hd-modal-content,
  .modal-content {
    max-width: 100% !important;
    width: 96vw !important;
    padding: 16px 14px !important;
  }
  .hd-bonus-add,
  .hd-allowance-add {
    grid-template-columns: 1fr 1fr !important;
    grid-template-rows: auto auto auto !important;
  }
  .hd-bonus-add label,
  .hd-allowance-add label { grid-column: span 1; }
  .hd-bonus-add .btn,
  .hd-allowance-add .btn { grid-column: 1 / -1 !important; }
}

/* Phase 5B: HQ / Agency portal shells. On phones, shrink the shell
 * padding and stack 2-column form rows so cards/forms never trigger
 * page-level horizontal scroll. */
@media (max-width: 640px) {
  .hq-shell, .ag-shell {
    padding-left: 10px !important;
    padding-right: 10px !important;
  }
  .form-row {
    grid-template-columns: 1fr !important;
  }
  .tile-row {
    /* Allow a single tile to take the full row instead of being
     * stuck at minmax(180px, 1fr) which can still squeeze badly. */
    grid-template-columns: 1fr !important;
  }
  /* Common card pattern used inline in hq.html / agency.html — when a
   * card sets max-width:640px but the parent shell is wider, the card
   * still sits at the natural intrinsic width. Force it back to 100%. */
  .hq-shell > div, .ag-shell > div {
    max-width: 100% !important;
  }
  /* Inline-styled banners with `display:flex` + `justify-content:space-between`
   * inside admin cards can refuse to wrap on narrow phones. Force them
   * to stack. Targets the stores billing summary and similar banners. */
  .admin-section [style*="display:flex"][style*="justify-content:space-between"],
  .admin-section [style*="display: flex"][style*="justify-content: space-between"] {
    flex-wrap: wrap !important;
  }
}

/* ---------- Buttons ---------- */
.btn {
  border: 1px solid #cfd4da;
  background: #fff;
  color: #222;
  border-radius: 8px;
  padding: 8px 14px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: background 0.15s, border-color 0.15s, box-shadow 0.15s;
  white-space: nowrap;
  font-family: inherit;
}
.btn:hover { background: #f6f7f9; }
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: #1f4f5b; border-color: #1f4f5b; color: #fff;
}
.btn-primary:hover { background: #163942; }
.btn-secondary {
  background: #6c757d; border-color: #6c757d; color: #fff;
}
.btn-secondary:hover { background: #545b62; }
.btn-dark {
  background: #2c2f33; border-color: #2c2f33; color: #fff;
}
.btn-dark:hover { background: #1c1f23; }
.btn-green {
  background: #1e7a3a; border-color: #1e7a3a; color: #fff;
}
.btn-green:hover { background: #185f2d; }
.btn-light {
  background: #fff; border-color: #cfd4da; color: #222;
}
.btn-danger {
  background: #b3261e; border-color: #b3261e; color: #fff;
}
.btn-danger:hover { background: #911e18; }
.btn-outline-danger {
  background: #fff; border: 1.5px solid #d23a2a; color: #d23a2a; font-weight: 600;
}
.btn-outline-danger:hover { background: #fff3f2; }
.btn-block { width: 100%; justify-content: center; }
.icon-only { padding: 8px 10px; }
.link-btn {
  background: none; border: none; color: #1f4f5b; cursor: pointer;
  padding: 8px 0; font-size: 13px; text-decoration: underline;
  display: block; margin: 8px auto 0;
  font-family: inherit;
}

/* ---------- Icons ---------- */
.icon-dl, .icon-print, .icon-key, .icon-out {
  width: 16px; height: 16px; display: inline-block;
  background-repeat: no-repeat; background-size: contain; background-position: center;
}
.icon-dl { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/><polyline points='7 10 12 15 17 10'/><line x1='12' y1='15' x2='12' y2='3'/></svg>"); }
.icon-print { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23222' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 6 2 18 2 18 9'/><path d='M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2'/><rect x='6' y='14' width='12' height='8'/></svg>"); }
.icon-key { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23222' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4'/></svg>"); }
.icon-out { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4'/><polyline points='16 17 21 12 16 7'/><line x1='21' y1='12' x2='9' y2='12'/></svg>"); }
.icon-gear { background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23222' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><circle cx='12' cy='12' r='3'/><path d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z'/></svg>"); }

/* ---------- Auth ---------- */
/* Both the business login (#auth-screen on /) and the HQ/Agency login
   (#login-screen on /hq, /agency) share the centered card layout. */
#auth-screen,
#login-screen {
  display: flex; align-items: center; justify-content: center;
  background: #f4f6f8; padding: 20px;
  min-height: 100vh;
}
/* When .hidden is set, the flex display rule above would still try to
   render it. Force hide. */
#auth-screen.hidden,
#login-screen.hidden { display: none; }
.auth-card {
  background: #fff; border-radius: 12px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.08);
  padding: 32px; width: 100%; max-width: 380px;
}
.auth-title {
  margin: 0 0 24px; text-align: center; font-size: 24px;
}
.auth-desc {
  font-size: 13px; color: #555; margin: 0 0 16px; line-height: 1.6;
}
.auth-label {
  display: block; font-size: 13px; color: #444;
  margin: 12px 0 6px; font-weight: 500;
}
.auth-input {
  width: 100%; padding: 10px 12px; border: 1px solid #cfd4da;
  border-radius: 8px; font-size: 14px; font-family: inherit;
  box-sizing: border-box; min-width: 0;
}
.auth-input:focus { outline: none; border-color: #1f4f5b; box-shadow: 0 0 0 2px rgba(31,79,91,0.15); }
.auth-error {
  color: #b3261e; font-size: 13px; margin: 10px 0; min-height: 16px;
}
.auth-card .btn-block { margin-top: 16px; }
.login-tabs {
  display: flex;
  border-bottom: 1px solid #cfd4da;
  margin-bottom: 18px;
}
.login-tab {
  flex: 1;
  background: none;
  border: none;
  padding: 10px;
  font-size: 14px;
  color: #777;
  cursor: pointer;
  border-bottom: 2px solid transparent;
  font-family: inherit;
}
.login-tab.active {
  color: #1f4f5b;
  border-bottom-color: #1f4f5b;
  font-weight: 600;
}
.recovery-code {
  background: #f4f6f8; border: 1.5px dashed #888;
  padding: 18px; text-align: center; font-size: 22px;
  font-weight: 700; letter-spacing: 2px; margin: 12px 0;
  font-family: ui-monospace, "SF Mono", Consolas, monospace;
  user-select: all;
}

/* ---------- App Header ---------- */
.app-header {
  display: flex; justify-content: space-between; align-items: center;
  padding: 16px 20px; gap: 16px; flex-wrap: wrap;
}
.header-left, .header-right {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
}
/* 非マイページの共通ヘッダー: ☰ の右隣にページ名を置く。 */
.app-header .hdr-title { margin: 0; font-size: 18px; font-weight: 700; white-space: nowrap; }
/* 月切替ページ共通(給与明細/打刻履歴と統一)。ヘッダー直下に
   [‹前の月  2026年6月  次の月›] を同じ余白・同じ見た目で置く。 */
/* 給与明細などと同じ「ヘッダー直下のインセット・カード」。full幅で白くつながらず、
   左右に余白のある白カードにして全ページの見た目を統一する。 */
.page-head { background: #fff; border: 1px solid #e3e6ea; border-radius: 10px; margin: 14px 16px; }
.month-picker { display: flex; align-items: center; justify-content: center; gap: 12px; flex-wrap: wrap; padding: 12px 16px; }
.month-picker .month-title { margin: 0; min-width: 120px; text-align: center; font-size: 16px; font-weight: 600; }
/* 言語切替は月ナビ（前の月/月/次の月）の塊から離し、右側へ寄せて全ページで
   一貫配置にする。flex-wrap 時も行末に収まり、月ナビの間に挟まらない。 */
.app-header .header-left .header-lang { margin-left: auto; }
.month-title {
  margin: 0 6px; font-size: 18px; font-weight: 600;
  min-width: 130px; text-align: center;
}

/* ---------- Staff section ---------- */
.staff-section {
  border: 1px solid #e0e3e7; border-radius: 8px;
  padding: 14px 18px; margin: 0 20px 18px;
}
.section-title {
  margin: 0 0 12px; font-size: 14px; font-weight: 500; color: #444;
}
.staff-add-row {
  display: flex; gap: 8px; margin-bottom: 12px;
}
.staff-input {
  flex: 0 0 240px; padding: 8px 12px;
  border: 1px solid #cfd4da; border-radius: 8px; font-size: 14px;
  font-family: inherit;
}
.staff-input:focus { outline: none; border-color: #1f4f5b; }
.staff-chips {
  display: flex; flex-wrap: wrap; gap: 8px;
}
.chip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid #cfd4da; border-radius: 22px;
  padding: 5px 12px 5px 6px; background: #fff;
  font-size: 14px; cursor: grab; user-select: none;
}
.chip.dragging { opacity: 0.4; }
.chip-handle {
  color: #999; cursor: grab; font-size: 13px; line-height: 1;
  letter-spacing: -2px;
}
.chip-name { padding: 0 4px; }
.chip-remove {
  width: 18px; height: 18px; border-radius: 50%;
  background: transparent; border: none; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  color: #888; font-size: 14px; font-family: inherit;
}
.chip-remove:hover { background: #f0f0f0; color: #222; }

/* ---------- Shift table ---------- */
#shift-tables { padding: 0 20px 30px; }
.week-table {
  width: 100%; border-collapse: collapse;
  margin-bottom: 14px; table-layout: fixed;
}
.week-table th, .week-table td {
  border: 1px solid #d8dbe0; padding: 6px 4px;
  text-align: center; vertical-align: middle;
  font-size: 13px; height: 34px;
}
.week-table th { font-weight: 600; }
.col-no { width: 36px; }
.col-name { width: 80px; }
.col-time { width: auto; }
.col-total { width: 70px; }
.total-header { background: #eeeeee; font-weight: 600; }
.total-cell { font-weight: 700; background: #fafafa; }

.week-publish-bar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: #fffaf0;
  border: 1px solid #f0dcb0;
  border-radius: 6px;
  padding: 6px 12px;
  margin: 14px 0 4px;
  font-size: 12.5px;
}
.week-publish-bar.published {
  background: #e8f7ee;
  border-color: #cfe9d8;
}
.week-pub-label { color: #555; }
.week-publish-bar.published .week-pub-label { color: #1e7a3a; }
.week-bar-actions { display: inline-flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.btn-sm { padding: 4px 10px; font-size: 12px; }
/* Touch devices: keep small buttons compact on desktop but give a comfortable
   tap target on phones/tablets (pointer:coarse). */
@media (pointer: coarse) { .btn-sm { min-height: 40px; } }
.dow-header { font-weight: 600; }
.dow-mon, .dow-wed, .dow-fri, .dow-sun { background: #fff200; }
.dow-sat { background: #cfe2f3; }
.date-cell { font-weight: 700; }
.date-sat { color: #1f4e78; }
.date-sun { color: #c00; }
.staff-no { color: #999; font-weight: 600; }
.name-cell { text-align: left; padding-left: 10px; font-weight: 500; }
.shift-cell {
  cursor: pointer; padding: 0;
}
.shift-cell:hover { background: #f5f8fa; }
.shift-cell-inner {
  display: grid; grid-template-columns: 1fr 1fr;
  height: 100%; min-height: 28px;
  min-width: 0;
}
.shift-time {
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 12.5px; padding: 4px 2px;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: clip;
}
.shift-time:first-child {
  border-right: 1px solid #d8dbe0;
}
.shift-time.last { color: #c00; }

/* Mobile: stack start/end vertically so narrow day-columns never overflow.
   Stronger cell borders so start/end pair clearly reads as one shift. */
@media (max-width: 720px) {
  .week-table { border: 1.5px solid #8a929c; }
  .week-table th, .week-table td {
    font-size: 11px; padding: 3px 1px; height: auto;
    border: 1.5px solid #8a929c;
  }
  .col-no { width: 22px; }
  .col-name { width: 54px; }
  .name-cell { padding-left: 4px; font-size: 11px; }
  .shift-cell { background: #fbfbfd; }
  .shift-cell:empty, .shift-cell.no-day { background: #f3f3f5; }
  .shift-cell-inner {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr 1fr;
    min-height: 36px;
  }
  .shift-time {
    font-size: 10.5px; padding: 2px 1px;
  }
  .shift-time:first-child {
    border-right: none;
    border-bottom: 1px dashed #b0b6bd;
  }
  #shift-tables { padding: 0 4px 20px; }
}
.no-day { background: #f7f7f7; cursor: default; }
.no-day:hover { background: #f7f7f7; }
.shift-cell.other-month { background: #fafafa; }
.shift-cell.other-month .shift-time { color: #888; }
.date-cell.other-month { color: #aaa; font-weight: 400; }

/* Monthly summary table */
.summary-section {
  margin: 30px 0 20px;
}
.summary-title {
  font-size: 15px; font-weight: 600; margin: 0 0 10px;
}
.summary-table {
  width: 100%; border-collapse: collapse;
  max-width: 520px;
}
.summary-table th, .summary-table td {
  border: 1px solid #d8dbe0; padding: 8px 12px;
  text-align: center; font-size: 13px;
}
.summary-table th {
  background: #eeeeee; font-weight: 600;
}
.summary-table .sum-name {
  text-align: left; font-weight: 500;
}
.summary-table .sum-total {
  font-weight: 700;
}
.hint-text {
  font-size: 12px; color: #666; margin: 4px 0 8px;
}

/* ---------- Modal ---------- */
.modal {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center;
}
.modal-overlay {
  position: absolute; inset: 0; background: rgba(0,0,0,0.4);
}
.modal-content {
  position: relative; background: #fff; border-radius: 12px;
  padding: 22px 22px 18px; width: 92%; max-width: 380px;
  box-shadow: 0 10px 40px rgba(0,0,0,0.2);
}
.modal-title {
  margin: 0 0 12px; text-align: center; font-size: 16px; font-weight: 600;
}
.modal-content hr {
  border: none; border-top: 1px solid #e0e3e7; margin: 0 0 16px;
}
.time-row {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 12px; margin-bottom: 14px;
}
.time-col { min-width: 0; }
.time-col label {
  display: block; font-size: 13px; color: #555; margin-bottom: 6px;
}
.time-col input[type=time] {
  width: 100%; padding: 10px; border: 1px solid #cfd4da;
  border-radius: 8px; font-size: 15px; text-align: center;
  font-family: inherit; box-sizing: border-box;
}
.modal-buttons {
  display: flex; gap: 8px; margin-top: 14px; justify-content: center;
}
.modal-buttons .btn { flex: 1; justify-content: center; }
#last-toggle.active {
  background: #1f4f5b; color: #fff; border-color: #1f4f5b;
}
#sr-last-toggle.active {
  background: #1f4f5b; color: #fff; border-color: #1f4f5b;
}
.request-hint-row {
  background: #fff8ec;
  border: 1px solid #f0dcb0;
  border-radius: 6px;
  padding: 10px 12px;
  margin-bottom: 14px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.request-hint-text {
  font-size: 13px;
  color: #555;
}
.request-hint-text .hint-strong {
  font-weight: 700;
  color: #1f4f5b;
}
.request-hint-text.ng .hint-strong {
  color: #b3261e;
}

.template-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  background: #f4f6f8;
  border-radius: 6px;
  padding: 8px 10px;
  margin-bottom: 12px;
}
.template-chips .tpl-label {
  font-size: 12px;
  color: #666;
  margin-right: 4px;
}
.template-chips .tpl-chip {
  border: 1px solid #4a86b3;
  background: #fff;
  color: #1f4e78;
  border-radius: 14px;
  padding: 4px 10px;
  font-size: 12px;
  cursor: pointer;
  font-family: inherit;
}
.template-chips .tpl-chip:hover { background: #e8f0f9; }

.shift-cell.dragging { opacity: 0.4; }
.shift-cell.drag-over { background: #fff3d0; outline: 2px dashed #c97b00; outline-offset: -2px; }

.week-table .cost-row td {
  background: #f7f9fb;
  font-weight: 700;
  font-size: 13px;
  height: 32px;
  padding: 6px 10px;
}
.week-table .cost-row .cost-label {
  text-align: right;
  color: #555;
}
.week-table .cost-row .cost-value {
  text-align: right;
  color: #1f4f5b;
  font-family: ui-monospace, Consolas, monospace;
}

/* ---------- Toast ---------- */
.toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  background: #222; color: #fff; padding: 10px 18px;
  border-radius: 6px; z-index: 2000; font-size: 14px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}

/* ---------- Print ---------- */
.print-only { display: none; }

@media print {
  *, *::before, *::after {
    -webkit-print-color-adjust: exact !important;
    print-color-adjust: exact !important;
    color-adjust: exact !important;
  }
  .no-print { display: none !important; }
  .print-only { display: block; }
  /* Injected top strips (メール認証 / 規約同意) must never appear on a printout
     such as the 給与明細書 — they pushed the slip onto a blank 2nd page. */
  #fx-verify-banner, #fx-consent-banner { display: none !important; }
  body { background: #fff; }
  /* The on-screen layout forces .screen { min-height:100vh } so short pages
     still fill the viewport. In print that reserved full-page height spilled a
     trailing margin onto a blank 2nd page — reset every wrapper to content
     height and strip trailing margins so a short month prints on one page. */
  html, body, #app-screen, #schedule-screen, #shift-tables, #schedule-tables {
    min-height: 0 !important;
    height: auto !important;
    margin-bottom: 0 !important;
    padding-bottom: 0 !important;
  }
  .screen { min-height: 0 !important; }
  #shift-tables > *:last-child,
  #schedule-tables > *:last-child,
  .week-block:last-child,
  .week-block:last-child .week-table { margin-bottom: 0 !important; }
  /* Hide chrome (header, sidebar, footer) during print */
  .staff-section { display: none; }
  footer { display: none !important; }
  #shift-tables { padding: 0; }
  .week-publish-bar { display: none; }
  /* Hide cost row + weekly total column when printing (employees may receive printouts).
     Actual <col>/<th>/<td>/<tr> removal is done in JS (beforeprint/afterprint) so the
     fixed table layout keeps day columns equal width. CSS here is a fallback only. */
  .week-table .cost-row { display: none !important; }
  .week-table .total-header,
  .week-table .total-cell { display: none !important; }
  .week-table .col-total { width: 0 !important; }
  .week-table {
    page-break-inside: avoid;
    margin-bottom: 14px;
  }
  .week-table th, .week-table td {
    font-size: 11px; padding: 3px 2px; height: auto;
  }
  .print-title-only {
    text-align: center; margin: 0 0 14px;
  }
  .print-title-only h1 {
    margin: 8px 0; font-size: 16px; font-weight: 600;
  }
  /* 月間合計勤務時間 is for on-screen reference only — keep it off the
     printed shift sheet that staff receive. */
  .summary-section { display: none !important; }
  /* @page orientation: default is the browser's portrait. Landscape is applied
     only on the shift page by toggling the external /print-landscape.css <link>
     (CSP-safe). No global @page here so other print pages keep their own margins. */

  /* Single-week print mode (週(縦)/週(横) buttons). app.js tags body with
     .week-print-mode and the chosen week-block with .print-target. Moved here
     from an injected <style> so it works under the strict CSP. */
  body.week-print-mode .week-block:not(.print-target) { display: none !important; }
  body.week-print-mode .summary-section { display: none !important; }
  body.week-print-mode footer, body.week-print-mode .no-print { display: none !important; }
  body.week-print-mode .week-block.print-target { width: 100% !important; margin: 0 !important; padding: 0 !important; }
  body.week-print-mode .week-block.print-target .week-table { width: 100% !important; margin: 0 !important; page-break-inside: auto; table-layout: fixed; }
  body.week-print-mode .week-block.print-target .week-table th,
  body.week-print-mode .week-block.print-target .week-table td { font-size: 12px !important; padding: 6px 4px !important; line-height: 1.3 !important; }
  body.week-print-mode .week-block.print-target .week-table tbody tr { page-break-inside: avoid; }
}

/* Mobile overflow safety net (smartphone QA). Keeps all form controls inside
   their container, stacks the shift / 希望シフト time modal's 開始/終了 on narrow
   phones (they were overlapping), and prevents any stray element from forcing a
   horizontal PAGE scroll — which made full-width fields run off the right edge.
   Wide tables keep their own .mobile-scroll horizontal scroll (unaffected). */
@media (max-width: 720px) {
  input, select, textarea { max-width: 100%; min-width: 0; box-sizing: border-box; }
  .time-row { grid-template-columns: 1fr; }
  html, body { overflow-x: hidden; }
}

/* iOS (and some Android) render native <input type=time|date> and <select> at an
   intrinsic width that ignores width:100%/max-width, so they overflow narrow
   modals & cards (shift/希望シフト time modal, 賃金ルールの深夜/閉店時刻, スタッフ
   入社日, 深夜手当/丸め単位の select). appearance:none makes them honour the CSS
   width; tapping still opens the native picker. <select> gets a custom arrow back. */
input[type="time"], input[type="date"] {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
}
select.auth-input {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='12'%20height='8'%3E%3Cpath%20fill='%23666'%20d='M1%201l5%205%205-5'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 10px center;
  padding-right: 28px;
}

/* Comprehensive iOS select fix: on phones, EVERY <select> — ERP form grids,
   modal pickers (諸手当の種類 等), filters, store selectors — gets
   appearance:none so its native intrinsic width can't push a grid/modal past the
   viewport edge. A consistent arrow is drawn back. padding-right is !important so
   it wins over the inline `padding:` many of these selects set via style="". */
@media (max-width: 720px) {
  select {
    -webkit-appearance: none; -moz-appearance: none; appearance: none;
    background-image: url("data:image/svg+xml;charset=US-ASCII,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='12'%20height='8'%3E%3Cpath%20fill='%23666'%20d='M1%201l5%205%205-5'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 8px center;
    padding-right: 26px !important;
  }
}

/* Notification bell dropdown: on phones the bell can sit on the LEFT of the
   header, but the dropdown opens with right:0 + width:340px (set inline by
   notification-bell.js), so it ran off the LEFT edge of the screen. On narrow
   viewports, pin it as a fixed tray that spans the viewport width instead. */
@media (max-width: 640px) {
  #fx-bell-dropdown {
    position: fixed !important;
    top: 58px !important;
    left: 8px !important;
    right: 8px !important;
    width: auto !important;
    max-width: none !important;
    max-height: 70vh !important;
  }
}

/* Shift section tabs (月表 / 日別AI配置) — unified shift navigation (mig 018) */
.shift-tabs {
  display: flex;
  gap: 6px;
  margin: 10px 4px 0;
  border-bottom: 2px solid #e3e6ea;
}
.publish-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
  margin: 10px 4px 0;
  padding: 8px 12px;
  background: #f7f9fb;
  border: 1px solid #e3e8ec;
  border-radius: 8px;
}
.publish-bar-hint { font-size: 12px; color: #78808a; }
.shift-tab {
  padding: 8px 16px;
  font-size: 13px;
  font-weight: 600;
  color: #607d8b;
  text-decoration: none;
  border: 1px solid transparent;
  border-bottom: none;
  border-radius: 8px 8px 0 0;
  margin-bottom: -2px;
}
.shift-tab:hover { background: #f0f4f5; color: #1f4f5b; }
.shift-tab.active {
  background: #fff;
  color: #1f4f5b;
  border-color: #e3e6ea;
  border-bottom: 2px solid #fff;
}
