/* ============================================================================
   DayFlowPro — modal-system.css
   Place at: lib/phase3/modal-system.css
   Load AFTER theme.css:
       <link rel="stylesheet" href="lib/phase3/theme.css">
       <link rel="stylesheet" href="lib/phase3/modal-system.css">

   A frosted-glass modal system. Mobile = bottom sheet with a grip.
   Desktop = centred floating dialog. Same markup, no JS branching.

   MARKUP CONTRACT
   ---------------
   <div class="dfp-modal dfp-modal--sheet">              <!-- overlay/scrim -->
     <div class="dfp-modal__panel" style="--dfp-modal-w:640px">
       <div class="dfp-modal__head">
         <div class="dfp-modal__grip"></div>             <!-- optional -->
         <h3 class="dfp-modal__title">New Booking</h3>
         <p  class="dfp-modal__sub">optional subtitle</p>
         <button class="dfp-modal__close" aria-label="Close"></button>
       </div>
       ... form content, any markup ...
       <div class="dfp-modal__foot"><button>Save</button></div>
     </div>
   </div>

   The PANEL is the scroll container; __head and __foot are sticky inside it.
   That means no body wrapper is required — drop-in over existing children.
   ========================================================================== */

/* ---- 1. Tokens ----------------------------------------------------------- */
:root {
  /* Scrim behind the modal */
  --dfp-m-scrim:      rgba(18, 24, 33, 0.38);
  --dfp-m-blur:       22px;

  /* Panel body: near-opaque so text stays crisp, with a whisper of the
     blurred page showing through at the edges. */
  --dfp-m-glass:      rgba(255, 255, 255, 0.86);
  --dfp-m-glass-solid:#FFFFFF;

  /* Hairline + the light-catching top edge that sells the glass */
  --dfp-m-hair:       rgba(16, 24, 40, 0.10);
  --dfp-m-sheen:      rgba(255, 255, 255, 0.85);

  /* Recessed field surface inside a glass panel */
  --dfp-m-well:       rgba(16, 24, 40, 0.035);
  --dfp-m-well-hair:  rgba(16, 24, 40, 0.11);

  --dfp-m-text:       #16181D;
  --dfp-m-muted:      #5B6472;

  --dfp-m-shadow:
     0 1px 1px rgba(16,24,40,0.04),
     0 8px 20px -6px rgba(16,24,40,0.14),
     0 32px 64px -16px rgba(16,24,40,0.24);

  /* Geometry */
  --dfp-m-r:          26px;   /* desktop panel radius */
  --dfp-m-r-sheet:    28px;   /* mobile top corners */
  --dfp-m-pad:        22px;   /* horizontal panel padding */
  --dfp-m-pad-t:      0px;    /* head supplies its own top padding */
  --dfp-m-pad-b:      22px;
  --dfp-m-w:          640px;  /* default max width, override per modal */

  /* Motion */
  --dfp-m-ease:       cubic-bezier(0.16, 0.84, 0.24, 1);
  --dfp-m-dur:        320ms;
}

[data-theme="dark"] {
  --dfp-m-scrim:      rgba(4, 7, 12, 0.62);
  --dfp-m-blur:       24px;

  --dfp-m-glass:      rgba(28, 33, 41, 0.88);
  --dfp-m-glass-solid:#1C2129;

  --dfp-m-hair:       rgba(255, 255, 255, 0.09);
  --dfp-m-sheen:      rgba(255, 255, 255, 0.16);

  --dfp-m-well:       rgba(0, 0, 0, 0.28);
  --dfp-m-well-hair:  rgba(255, 255, 255, 0.10);

  --dfp-m-text:       #E9ECF2;
  --dfp-m-muted:      #9BA5B4;

  --dfp-m-shadow:
     0 1px 1px rgba(0,0,0,0.5),
     0 12px 28px -8px rgba(0,0,0,0.55),
     0 40px 80px -20px rgba(0,0,0,0.7);
}

/* ---- 2. Overlay / scrim -------------------------------------------------- */
.dfp-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  justify-content: center;
  align-items: flex-end;              /* mobile: sheet sits on the bottom */
  padding: 0;

  background: var(--dfp-m-scrim);
  -webkit-backdrop-filter: blur(var(--dfp-m-blur)) saturate(1.35);
  backdrop-filter: blur(var(--dfp-m-blur)) saturate(1.35);

  animation: dfpModalIn 220ms var(--dfp-m-ease) both;
  overscroll-behavior: contain;
}

/* Progressive enhancement: if blur is unsupported, deepen the scrim so the
   modal still separates from the page. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .dfp-modal { background: rgba(18, 24, 33, 0.62); }
  [data-theme="dark"] .dfp-modal { background: rgba(4, 7, 12, 0.8); }
}

@keyframes dfpModalIn { from { opacity: 0 } to { opacity: 1 } }

/* ---- 3. Panel ------------------------------------------------------------ */
.dfp-modal__panel {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  max-width: var(--dfp-modal-w, var(--dfp-m-w));

  /* Mobile sheet: tall but never past the grabbable top of the screen. */
  max-height: 92vh;   /* fallback */
  max-height: 92dvh;
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;

  padding: var(--dfp-m-pad-t) var(--dfp-m-pad) var(--dfp-m-pad-b);
  /* Home-indicator / notch safety on iOS */
  padding-bottom: calc(var(--dfp-m-pad-b) + env(safe-area-inset-bottom, 0px));

  border-radius: var(--dfp-m-r-sheet) var(--dfp-m-r-sheet) 0 0;
  background: var(--dfp-m-glass);
  color: var(--dfp-m-text);
  box-shadow: var(--dfp-m-shadow), inset 0 1px 0 var(--dfp-m-sheen);
  border: 1px solid var(--dfp-m-hair);
  border-bottom: 0;

  animation: dfpSheetUp 380ms var(--dfp-m-ease) both;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .dfp-modal__panel { background: var(--dfp-m-glass-solid); }
}

@keyframes dfpSheetUp {
  from { transform: translate3d(0, 100%, 0); }
  to   { transform: translate3d(0, 0, 0); }
}

/* Kill the default focus halo on the panel itself (it gets focus() for a11y)
   without removing it from real controls. */
.dfp-modal__panel:focus { outline: none; }

/* ---- 4. Sticky header ---------------------------------------------------- */
.dfp-modal__head {
  position: sticky;
  top: 0;
  z-index: 6;

  /* Full-bleed: cancel the panel's side padding, then re-add it.
     Extra right padding reserves room for the absolutely-placed close button,
     so the title can never slide underneath it. */
  margin: 0 calc(-1 * var(--dfp-m-pad)) 18px;
  padding: 14px calc(var(--dfp-m-pad) + 46px) 14px var(--dfp-m-pad);

  /* Single column + absolute close = the header accepts any number of
     children (eyebrow, title, subtitle, badge) in any order without the
     layout breaking. */
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
  gap: 0;

  background: var(--dfp-m-glass);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  backdrop-filter: blur(18px) saturate(1.4);
  border-bottom: 1px solid var(--dfp-m-hair);
  border-radius: var(--dfp-m-r-sheet) var(--dfp-m-r-sheet) 0 0;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .dfp-modal__head { background: var(--dfp-m-glass-solid); }
}

/* Grip: sits above everything else in the header. */
.dfp-modal__grip {
  /* Optically centre in the panel, not in the padding-shifted header box. */
  margin-right: -46px;
  justify-self: center;
  width: 42px;
  height: 4px;
  border-radius: 999px;
  background: currentColor;
  opacity: 0.22;
  margin-bottom: 10px;
}

.dfp-modal__title {
  margin: 0;
  min-width: 0;
  font-family: 'Fraunces', Georgia, serif;
  font-size: clamp(20px, 5.2vw, 25px);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.15;
  color: var(--dfp-m-text);

  /* The signature: title text carries the accent as a gradient wash. */
  background: linear-gradient(
    100deg,
    var(--dfp-m-text) 0%,
    var(--dfp-m-text) 32%,
    var(--accent, #3B82F6) 130%
  );
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}

/* Fallback for engines that ignore background-clip:text */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .dfp-modal__title { -webkit-text-fill-color: currentColor; color: var(--dfp-m-text); }
}

.dfp-modal__sub {
  margin: 3px 0 0;
  font-size: 13px;
  line-height: 1.45;
  color: var(--dfp-m-muted);
}

/* Eyebrow chip — small accent label above a title, e.g. "WEDDING · 90 MIN" */
.dfp-modal__eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: max-content;
  margin: 0 0 8px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--accent, #3B82F6);
  background: var(--accent-soft, rgba(59,130,246,0.12));
  border: 1px solid color-mix(in srgb, var(--accent, #3B82F6) 28%, transparent);
}

/* ---- 5. Close button ---------------------------------------------------- */
.dfp-modal__close {
  /* Absolute, so the header's child list can grow without disturbing it. */
  position: absolute;
  top: 14px;
  right: var(--dfp-m-pad);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: 0 0 auto;
  padding: 0;
  border: 1px solid var(--dfp-m-hair);
  border-radius: 12px;
  background: var(--dfp-m-well);
  color: var(--dfp-m-muted);
  cursor: pointer;
  font: 400 20px/1 system-ui, sans-serif;
  transition: background 160ms ease, color 160ms ease, transform 160ms ease;
}
.dfp-modal__close::before { content: "\00d7"; display: block; margin-top: -2px; }
.dfp-modal__close:hover {
  background: color-mix(in srgb, var(--accent, #3B82F6) 14%, transparent);
  color: var(--accent, #3B82F6);
  transform: rotate(90deg);
}
.dfp-modal__close:active { transform: rotate(90deg) scale(0.92); }

/* A grip pushes the close button down so both stay clear of each other. */
.dfp-modal__head:has(.dfp-modal__grip) .dfp-modal__close { top: 26px; }

/* ---- 6. Sticky footer / primary action ---------------------------------- */
.dfp-modal__foot {
  position: sticky;
  /* bottom:0 pins the footer's bottom edge to the scrollport edge, so it is
     never partly clipped. The negative bottom margin lets it bleed into the
     panel's bottom padding instead of stacking on top of it. */
  bottom: 0;
  z-index: 6;

  margin: 22px calc(-1 * var(--dfp-m-pad))
          calc(-1 * (var(--dfp-m-pad-b) + env(safe-area-inset-bottom, 0px)));
  padding: 14px var(--dfp-m-pad)
           calc(16px + env(safe-area-inset-bottom, 0px));

  display: flex;
  gap: 10px;

  background: var(--dfp-m-glass);
  -webkit-backdrop-filter: blur(18px) saturate(1.4);
  backdrop-filter: blur(18px) saturate(1.4);
  border-top: 1px solid var(--dfp-m-hair);
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .dfp-modal__foot { background: var(--dfp-m-glass-solid); }
}

.dfp-modal__foot > button { flex: 1 1 auto; min-height: 50px; }
.dfp-modal__foot > button.dfp-modal__ghost { flex: 0 0 auto; min-width: 104px; }

/* Give the app's gradient CTA a proper lift + press response. Inline styles
   set background/color, so we only add what they don't. */
.dfp-modal__foot > button {
  border-radius: 14px;
  box-shadow: 0 1px 2px rgba(16,24,40,0.10),
              0 8px 20px -8px color-mix(in srgb, var(--accent, #3B82F6) 55%, transparent);
  transition: transform 140ms var(--dfp-m-ease), box-shadow 200ms ease, filter 160ms ease;
}
.dfp-modal__foot > button:hover  { transform: translateY(-1px); filter: saturate(1.08) brightness(1.04); }
.dfp-modal__foot > button:active { transform: translateY(0) scale(0.988); }

/* ---- 7. Section grouping inside a modal -------------------------------- */
/* Opt-in wrapper that visually clusters related fields. */
.dfp-modal__section {
  margin: 0 0 16px;
  padding: 16px;
  border-radius: 18px;
  background: var(--dfp-m-well);
  border: 1px solid var(--dfp-m-hair);
}
.dfp-modal__section-title {
  margin: 0 0 12px;
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--dfp-m-muted);
}
.dfp-modal__section-title::before {
  content: "";
  width: 3px;
  height: 13px;
  border-radius: 999px;
  background: var(--accent, #3B82F6);
}

/* Two-up field row that collapses on narrow screens. */
.dfp-modal__row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
  gap: 12px;
  margin-bottom: 14px;
}

/* Notice / callout blocks */
.dfp-modal__note {
  margin: 0 0 14px;
  padding: 12px 14px;
  border-radius: 14px;
  font-size: 13px;
  line-height: 1.5;
  background: var(--accent-soft, rgba(59,130,246,0.10));
  border: 1px solid color-mix(in srgb, var(--accent, #3B82F6) 26%, transparent);
  color: var(--dfp-m-text);
}
.dfp-modal__note--warn {
  background: rgba(245, 158, 11, 0.12);
  border-color: rgba(245, 158, 11, 0.34);
}
.dfp-modal__note--danger {
  background: rgba(239, 68, 68, 0.12);
  border-color: rgba(239, 68, 68, 0.34);
}

/* ---- 7b. Segmented control (modal sub-tabs) ---------------------------- */
.dfp-seg {
  display: flex;
  gap: 4px;
  margin-bottom: 18px;
  padding: 4px;
  border-radius: 14px;
  background: var(--dfp-m-well);
  border: 1px solid var(--dfp-m-hair);
  overflow-x: auto;
  scrollbar-width: none;
}
.dfp-seg::-webkit-scrollbar { display: none; }

.dfp-seg__btn {
  flex: 1 1 auto;
  min-width: max-content;
  min-height: 38px;
  padding: 8px 14px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--dfp-m-muted);
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background 160ms ease, color 160ms ease, box-shadow 200ms ease;
}
.dfp-seg__btn:hover { color: var(--dfp-m-text); }
.dfp-seg__btn.is-active {
  background: var(--dfp-m-glass-solid);
  color: var(--accent, #3B82F6);
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.08),
              0 2px 6px -2px rgba(16, 24, 40, 0.10);
}
[data-theme="dark"] .dfp-seg__btn.is-active {
  background: rgba(255, 255, 255, 0.08);
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.06);
}

/* ---- 8. Field polish inside modals ------------------------------------- */
/* Additive only — inline styles that already set a property win. */
.dfp-modal input:not([type="checkbox"]):not([type="radio"]),
.dfp-modal select,
.dfp-modal textarea {
  min-height: 46px;
  border-radius: 12px;
  transition: border-color 160ms ease, box-shadow 200ms ease, background 160ms ease;
}
.dfp-modal textarea { min-height: 92px; resize: vertical; line-height: 1.5; }

.dfp-modal input:hover:not(:disabled),
.dfp-modal select:hover:not(:disabled),
.dfp-modal textarea:hover:not(:disabled) {
  border-color: color-mix(in srgb, var(--accent, #3B82F6) 40%, transparent);
}
.dfp-modal input:focus,
.dfp-modal select:focus,
.dfp-modal textarea:focus {
  outline: none;
  border-color: var(--accent, #3B82F6);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--accent, #3B82F6) 18%, transparent);
}

/* Native selects get a custom chevron so they stop looking like 2009. */
.dfp-modal select {
  -webkit-appearance: none;
  appearance: none;
  padding-right: 40px;
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238A93A2' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 13px center;
  background-size: 17px 17px;
}

.dfp-modal input[type="checkbox"],
.dfp-modal input[type="radio"] {
  width: 19px;
  height: 19px;
  accent-color: var(--accent, #3B82F6);
  cursor: pointer;
}

/* iOS refuses to not zoom on inputs under 16px. Inline font-size wins over a
   plain rule, so this one narrow override earns its !important. */
@media (max-width: 640px) {
  .dfp-modal input,
  .dfp-modal select,
  .dfp-modal textarea {
    font-size: 16px !important;
    min-height: 50px;
  }
  .dfp-modal textarea { min-height: 104px; }
}

/* ---- 9. Desktop: centred floating dialog ------------------------------- */
@media (min-width: 768px) {
  :root { --dfp-m-pad: 30px; --dfp-m-pad-b: 26px; }

  .dfp-modal {
    align-items: center;
    padding: 32px 24px;
  }

  .dfp-modal__panel {
    max-height: min(88vh, 940px);
    border-radius: var(--dfp-m-r);
    border-bottom: 1px solid var(--dfp-m-hair);
    animation: dfpDialogIn 300ms var(--dfp-m-ease) both;
  }

  .dfp-modal__head {
    border-radius: var(--dfp-m-r) var(--dfp-m-r) 0 0;
    padding-top: 22px;
    padding-bottom: 16px;
    margin-bottom: 22px;
  }

  /* The grip is a touch affordance — pointless with a cursor. */
  .dfp-modal__grip { display: none; }
  .dfp-modal__head:has(.dfp-modal__grip) .dfp-modal__close { top: 22px; }
  .dfp-modal__close { top: 22px; }

  .dfp-modal__foot { padding-top: 16px; padding-bottom: 18px; }
  .dfp-modal__foot > button { min-height: 48px; }

  /* Wide modals get real two-column form layout. */
  .dfp-modal--wide { --dfp-modal-w: 860px; }
}

@keyframes dfpDialogIn {
  from { transform: translate3d(0, 14px, 0) scale(0.975); opacity: 0; }
  to   { transform: translate3d(0, 0, 0) scale(1); opacity: 1; }
}

@media (min-width: 1200px) {
  .dfp-modal__panel { max-height: min(86vh, 1000px); }
}

/* ---- 10. Variants ------------------------------------------------------- */

/* Default variant: bottom sheet on touch, centred dialog on desktop.
   Declared explicitly so the class is self-documenting in the markup rather
   than a bare marker that only the base rules happen to style. */
.dfp-modal--sheet { align-items: flex-end; }
@media (min-width: 768px) { .dfp-modal--sheet { align-items: center; } }

/* Compact confirm / alert dialog — centred at every size. */
.dfp-modal--confirm { align-items: center; padding: 24px 18px; }
.dfp-modal--confirm .dfp-modal__panel {
  --dfp-modal-w: 420px;
  border-radius: 22px;
  border-bottom: 1px solid var(--dfp-m-hair);
  padding: 26px 24px 22px;
  text-align: center;
  animation: dfpDialogIn 260ms var(--dfp-m-ease) both;
  max-height: 86vh;
  max-height: 86dvh;
}
.dfp-modal--confirm .dfp-modal__head {
  position: static;
  margin: 0 0 10px;
  padding: 0;
  border: 0;
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  display: block;
  text-align: center;
}
.dfp-modal--confirm .dfp-modal__foot {
  position: static;
  margin: 20px 0 0;
  padding: 0;
  border: 0;
  background: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
/* Big glyph at the top of a confirm dialog */
.dfp-modal__icon {
  width: 54px;
  height: 54px;
  margin: 0 auto 14px;
  display: grid;
  place-items: center;
  border-radius: 18px;
  font-size: 26px;
  background: var(--accent-soft, rgba(59,130,246,0.12));
  border: 1px solid color-mix(in srgb, var(--accent, #3B82F6) 26%, transparent);
}
.dfp-modal__icon--danger {
  background: rgba(239, 68, 68, 0.14);
  border-color: rgba(239, 68, 68, 0.36);
}

/* Right-hand side drawer — good for detail panes on desktop. */
@media (min-width: 1024px) {
  .dfp-modal--drawer { align-items: stretch; justify-content: flex-end; padding: 0; }
  .dfp-modal--drawer .dfp-modal__panel {
    --dfp-modal-w: 560px;
    max-height: 100vh;
    max-height: 100dvh;
    height: 100vh;
    height: 100dvh;
    border-radius: 24px 0 0 24px;
    animation: dfpDrawerIn 320ms var(--dfp-m-ease) both;
  }
  @keyframes dfpDrawerIn {
    from { transform: translate3d(100%, 0, 0); }
    to   { transform: translate3d(0, 0, 0); }
  }
}

/* Size shortcuts */
.dfp-modal--sm .dfp-modal__panel { --dfp-modal-w: 460px; }
.dfp-modal--md .dfp-modal__panel { --dfp-modal-w: 620px; }
.dfp-modal--lg .dfp-modal__panel { --dfp-modal-w: 780px; }
.dfp-modal--xl .dfp-modal__panel { --dfp-modal-w: 940px; }

/* ---- 11. Landscape phones ---------------------------------------------- */
@media (max-height: 520px) and (max-width: 950px) {
  .dfp-modal__panel { max-height: 96vh; max-height: 96dvh; }
  .dfp-modal__head { padding-top: 10px; padding-bottom: 10px; margin-bottom: 14px; }
  .dfp-modal__grip { display: none; }
  .dfp-modal__title { font-size: 19px; }
}

/* ---- 12. Quality floor -------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .dfp-modal,
  .dfp-modal__panel { animation: none !important; }
  .dfp-modal__close:hover { transform: none; }
  .dfp-modal__foot > button:hover { transform: none; }
}

@media (prefers-contrast: more) {
  :root { --dfp-m-glass: #FFFFFF; --dfp-m-hair: rgba(16,24,40,0.28); }
  [data-theme="dark"] { --dfp-m-glass: #14181F; --dfp-m-hair: rgba(255,255,255,0.28); }
  .dfp-modal { -webkit-backdrop-filter: none; backdrop-filter: none; }
}

/* Lock the page behind an open modal. Toggle this class on <body>. */
body.dfp-modal-open { overflow: hidden; }
