/* Duara mobile refinements.
 *
 * Everything here is scoped to phone widths, so the desktop design is
 * byte for byte what it was. Nothing changes content: this file only
 * adjusts spacing, type scale and tap target size, and styles the mobile
 * navigation drawer that mobile.js builds from the existing header links.
 *
 * Tailwind is loaded from the CDN and injects its utilities into the page
 * at runtime, which puts them after this stylesheet in the cascade. The few
 * rules below that have to beat a generated utility of equal specificity are
 * marked important for that reason and no other.
 */

@media (max-width: 767px) {

  /* --- Tap targets ------------------------------------------------------
   * Every button shaped link reaches 48px. Padding is left alone and
   * min-height does the work, so horizontal rhythm is unchanged and
   * nothing moves on wider screens. */

  /* Matched on the vertical padding utility as an exact word, which is what
   * decides the height, and on any rounded variant, which is what makes it a
   * button. py-4 and above already clear 48px and are left alone so card
   * sized links keep their own layout. */
  a[class*="rounded"][class~="py-1"],
  a[class*="rounded"][class~="py-1.5"],
  a[class*="rounded"][class~="py-2"],
  a[class*="rounded"][class~="py-2.5"],
  a[class*="rounded"][class~="py-3"],
  button[class*="rounded"][class~="py-1"],
  button[class*="rounded"][class~="py-1.5"],
  button[class*="rounded"][class~="py-2"],
  button[class*="rounded"][class~="py-2.5"],
  button[class*="rounded"][class~="py-3"],
  .dmn-panel a {
    min-height: 48px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }

  /* Footer link lists are the densest tap area on the site. */
  footer a {
    min-height: 48px;
    display: inline-flex;
    align-items: center;
  }

  /* Social icons are 32px circles on desktop. Give them a full target. */
  footer a[class*="w-8"][class*="h-8"] {
    width: 48px;
    height: 48px;
    justify-content: center;
  }

  /* --- Heading hierarchy ------------------------------------------------
   * This block used to pin four fixed pixel sizes here, because the desktop
   * scale was itself fixed and 64px does not fit a 360px screen. The scale in
   * fluid.css is now fluid and rem based, and its lower clamps land on the
   * same 36 / 28 / 20 steps this block was enforcing, so the sizes are no
   * longer restated at this width.
   *
   * They could not stay in any case: fluid.css loads after this file, so two
   * important declarations of equal specificity would resolve in its favour
   * and these would simply have stopped applying. The one rule with real
   * intent behind it, holding a display sized H2 a step below the H1 above
   * it, moved to fluid.css, where it still wins.
   *
   * --- Section rhythm ---------------------------------------------------
   * Sections are 80px top and bottom almost everywhere. These few were 64,
   * which reads as an inconsistent gap when scrolling. Element plus class
   * beats the utility on specificity, so no important needed. */

  section.py-16 { padding-top: 80px; padding-bottom: 80px; }
  section.py-8  { padding-top: 48px; padding-bottom: 48px; }

  /* Stacked two column layouts inherit an 80px gap meant for side by side
   * columns. Once stacked that reads as a section break rather than a gap. */
  .grid.gap-xl { gap: 48px; }

  /* --- Header -----------------------------------------------------------
   * The bar held a logo and two buttons, which overflows a 360px screen.
   * Client Login moves into the drawer, where it is easier to hit anyway.
   *
   * Marked important because the tap target rule above matches this same
   * link and carries higher specificity, so it would otherwise reinstate a
   * display value here. */

  header a[href*="my.duara.dev"],
  header a[href^="tel:"] { display: none !important; }

  /* The remaining action button had room for about eleven characters and
   * wrapped onto three lines. Tighter horizontal padding and no wrapping
   * keeps it on one line beside the logo and the menu button. */
  header a[href*="start-your-project"] {
    white-space: nowrap;
    padding-left: 12px;
    padding-right: 12px;
  }

  /* --- Overflow guard ---------------------------------------------------
   * Long unbroken strings such as URLs in body copy were the only thing
   * able to push the layout wider than the viewport. */

  main img, main table, main pre { max-width: 100%; }
  main p, main li, main h1, main h2, main h3 { overflow-wrap: break-word; }

  /* Decorative shapes are positioned outside their section on purpose, and a
   * 600px blob hanging off the right edge was widening the page on a phone.
   * Clip rather than hide, so sticky and absolute children keep working and
   * no new scroll container is created. */
  main section { overflow-x: clip; }

  /* --- Collapsed auto margins -------------------------------------------
   * The homepage hero images carry both mt-8 and mt-auto. Tailwind emits
   * mt-auto last, so it wins, and in a stacked column with no free space
   * auto resolves to zero. The result was an image sitting flush against
   * the buttons above it. Restoring the numeric value the markup already
   * asks for fixes the gap without touching desktop, where mt-auto still
   * does real work bottom aligning the two hero images against each other. */

  [class~="mt-auto"][class~="mt-4"]  { margin-top: 16px; }
  [class~="mt-auto"][class~="mt-6"]  { margin-top: 24px; }
  [class~="mt-auto"][class~="mt-8"]  { margin-top: 32px; }
  [class~="mt-auto"][class~="mt-12"] { margin-top: 48px; }
}

/* --- Mobile navigation sheet ---------------------------------------------
 * Built by mobile.js from the links already in the header, so no navigation
 * content is duplicated in the markup. Hidden entirely from 768px up, where
 * the existing desktop nav takes over unchanged.
 *
 * MOTION OWNERSHIP. The panel transform and the scrim opacity are written by
 * mobile.js every frame from a spring, so there is deliberately no transition
 * on either. A CSS transition here would fight the integrator: the finger
 * would move the sheet and the transition would smooth its way toward the
 * position the finger had already left, which is exactly the lag the spring
 * exists to remove. The only place a transition appears below is the reduced
 * motion fallback, where the spring never runs.
 */

.dmn-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: 14px;
  border: 1px solid rgb(23 29 28 / 0.12);
  background: transparent;
  color: inherit;
  cursor: pointer;
  flex: none;
  transition: background-color 120ms cubic-bezier(0.32, 0.72, 0, 1),
              transform 120ms cubic-bezier(0.32, 0.72, 0, 1);
}
/* Feedback on the press, not on the release. */
.dmn-toggle:active {
  transform: scale(0.94);
  background: rgb(23 29 28 / 0.05);
}

.dmn-toggle span {
  display: block;
  width: 20px;
  height: 2px;
  background: currentColor;
  position: relative;
  border-radius: 2px;
}
.dmn-toggle span::before,
.dmn-toggle span::after {
  content: "";
  position: absolute;
  left: 0;
  width: 20px;
  height: 2px;
  border-radius: 2px;
  background: currentColor;
}
.dmn-toggle span::before { top: -6px; }
.dmn-toggle span::after  { top: 6px; }

/* The icon is derived from the same number that positions the panel, so it
 * morphs continuously as the sheet is dragged rather than snapping when the
 * gesture ends. Halfway through a drag the control is halfway through its
 * change: the button shows the state the gesture is currently in.
 *
 * mobile.js writes --dmn-progress inline each frame. The attribute rule below
 * is the fallback for the reduced motion path, where the spring never runs and
 * nothing is ever written inline. */
.dmn-toggle { --dmn-progress: 0; }
.dmn-toggle[aria-expanded="true"] { --dmn-progress: 1; }

.dmn-toggle span { opacity: calc(1 - var(--dmn-progress)); }
.dmn-toggle span::before {
  transform: translateY(calc(6px * var(--dmn-progress)))
             rotate(calc(45deg * var(--dmn-progress)));
}
.dmn-toggle span::after {
  transform: translateY(calc(-6px * var(--dmn-progress)))
             rotate(calc(-45deg * var(--dmn-progress)));
}

/* --- Scrim ---------------------------------------------------------------
 * Dims the page to say the sheet is a modal task, and its opacity tracks the
 * drag continuously so a half-open sheet reads as half open. Pointer events
 * are toggled by script rather than by opacity, so a sheet caught mid-dismiss
 * can still be tapped away. */
.dmn-scrim {
  position: fixed;
  inset: 0;
  background: rgb(10 20 19 / 0.32);
  opacity: 0;
  pointer-events: none;
  z-index: 60;
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

/* --- Panel ---------------------------------------------------------------
 * A thick material: the heaviest surface on the site, because it is the one
 * that sits above everything else. */
.dmn-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: min(88vw, 400px);
  background: rgb(255 255 255 / 0.92);

  /* Saturation is held at 140%. At 190% the filter sampled the scrim-dimmed
   * teal page immediately behind the panel edge and pushed it to a vivid cyan,
   * which drew a bright stripe down the left side of the sheet: the filter
   * was inventing an accent colour the design does not have. */
  -webkit-backdrop-filter: saturate(140%) blur(40px);
  backdrop-filter: saturate(140%) blur(40px);

  box-shadow: -24px 0 60px -12px rgb(10 20 19 / 0.28);
  z-index: 70;
  transform: translate3d(100%, 0, 0);
  visibility: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: max(24px, env(safe-area-inset-top)) 20px
           max(24px, env(safe-area-inset-bottom)) 20px;
  display: flex;
  flex-direction: column;
  gap: 2px;

  /* Vertical scrolling stays with the browser; the horizontal axis is ours.
   * This is what lets a long menu scroll normally while still being
   * swipe-to-dismiss, with no manual axis locking. */
  touch-action: pan-y;
}
.dmn-panel:focus { outline: none; }

/* The sheet is allowed to overshoot when it is thrown open, which for a panel
 * pinned to the right edge would otherwise expose a gap behind it at the moment
 * it overshoots. This extends the material past the edge so the bounce has
 * something to show. It is never visible at rest. */
.dmn-panel::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 100%;
  width: 64px;
  background: inherit;
  -webkit-backdrop-filter: inherit;
  backdrop-filter: inherit;
}

/* --- Edge affordance -----------------------------------------------------
 * A strip along the right edge that summons the sheet, so it can be reached
 * without travelling to the corner. Narrow enough not to intercept taps on
 * content, and it only ever claims the gesture after 10px of horizontal
 * movement: a tap that lands here still reaches what is underneath. */
.dmn-edge {
  position: fixed;
  top: 25%;
  right: 0;
  width: 20px;
  height: 50%;
  z-index: 55;
  touch-action: pan-y;
}

/* --- Rows ---------------------------------------------------------------- */

.dmn-panel a {
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: flex-start;   /* the tap target rule centres buttons; menu rows read left */
  text-align: left;
  padding: 10px 14px;
  border-radius: 12px;
  text-decoration: none;
  color: #171d1c;                /* on-surface */
  font-size: 16px;
  line-height: 1.4;
  letter-spacing: 0em;           /* 16px: the body tier value */
  transition: background-color 120ms cubic-bezier(0.32, 0.72, 0, 1),
              transform 120ms cubic-bezier(0.32, 0.72, 0, 1);
}
.dmn-panel a:active {
  background: rgb(23 29 28 / 0.07);
  transform: scale(0.985);
}

.dmn-group {
  margin-top: 18px;
  padding: 8px 14px;
  font-size: 12px;
  letter-spacing: 0.09em;        /* 12px uppercase: the same value the 12px
                                  * tier uses everywhere else on the site */
  text-transform: uppercase;
  font-weight: 600;
  color: rgb(23 29 28 / 0.5);
}
.dmn-group:first-child { margin-top: 0; }

/* When the heading is also the section landing page it has to be tappable. */
a.dmn-group {
  display: flex;
  align-items: center;
  min-height: 44px;
  text-decoration: none;
  border-radius: 12px;
}
a.dmn-group:active { background: rgb(23 29 28 / 0.07); }

.dmn-cta {
  margin-top: 24px;
  justify-content: center !important;
  background: #375c58;           /* primary */
  color: #ffffff !important;
  font-weight: 600;
  box-shadow: 0 1px 2px rgb(10 20 19 / 0.12),
              0 8px 20px -8px rgb(10 20 19 / 0.35);
}

body[data-dmn-open="true"] { overflow: hidden; }

/* The site has no dark mode, so the sheet deliberately has none either.
 * A sheet that followed the system theme would not match the page behind it. */

/* --- Accessibility -------------------------------------------------------
 * Reduced motion replaces the slide with a cross fade in place: the same
 * state change, without moving a full-height surface across the viewport.
 * mobile.js detects the same signal and leaves the spring unstarted, so CSS
 * is the only thing driving the panel in this mode. */
@media (prefers-reduced-motion: reduce) {
  .dmn-panel {
    transform: none !important;
    opacity: 0;
    transition: opacity 200ms ease, visibility 200ms ease;
  }
  .dmn-panel[data-open="true"] { opacity: 1; visibility: visible !important; }
  .dmn-panel::after { display: none; }
  .dmn-scrim { transition: opacity 200ms ease; }
  .dmn-scrim[data-open="true"] { opacity: 1; }
  .dmn-edge { display: none; }   /* no gesture path when there is no gesture */
}

@media (prefers-reduced-transparency: reduce) {
  .dmn-panel {
    background: #ffffff;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .dmn-scrim {
    background: rgb(10 20 19 / 0.6);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
}

@media (prefers-contrast: more) {
  .dmn-panel { background: #ffffff; border-left: 1px solid rgb(23 29 28 / 0.45); }
  .dmn-panel a { color: #0d1211; }
  .dmn-group { color: rgb(23 29 28 / 0.75); }
  .dmn-toggle { border-color: rgb(23 29 28 / 0.45); }
}

@media (min-width: 768px) {
  .dmn-toggle, .dmn-scrim, .dmn-panel, .dmn-edge { display: none !important; }
}
