/* ==========================================================================
   components.css - mobile-first components.
   Base rules = locked mobile reference (870x1808).
   Desktop overrides live in responsive.css (>=1024px).
   ========================================================================== */

/* ---------------------------------------------------------------- header -- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: var(--surface);
  border-bottom: 1px solid rgba(15, 23, 42, 0.06);
  padding-top: var(--safe-t);
}

.site-header__inner {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--header-h-mobile);
  padding-inline: max(var(--safe-l), 0px) max(var(--safe-r), 0px);
}

.brand {
  display: inline-flex;
  align-items: center;
  flex: none;
}

.brand__logo {
  width: clamp(126px, 20.7vw, 180px);
  height: auto;
}

.brand__logo--desktop { display: none; }

.nav { display: none; }

.header-cta {
  margin-left: auto;
  flex: none;
}

/* hamburger */
.burger {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch);
  height: var(--touch);
  margin-right: -6px;
  border-radius: var(--r-sm);
}

.burger__box {
  position: relative;
  display: block;
  width: 24px;
  height: 16px;
}

.burger__bar {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2.5px;
  border-radius: 2px;
  background: var(--ink);
  transition: transform var(--dur) var(--ease), opacity var(--dur) var(--ease);
}

.burger__bar:nth-child(1) { top: 0; }
.burger__bar:nth-child(2) { top: 50%; transform: translateY(-50%); }
.burger__bar:nth-child(3) { bottom: 0; }

.burger[aria-expanded="true"] .burger__bar:nth-child(1) { transform: translateY(6.75px) rotate(45deg); }
.burger[aria-expanded="true"] .burger__bar:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] .burger__bar:nth-child(3) { transform: translateY(-6.75px) rotate(-45deg); }

/* ---------------------------------------------------------------- drawer -- */

.drawer {
  position: fixed;
  inset: 0;
  z-index: 45;
  display: grid;
  align-content: start;
  gap: 6px;
  padding: calc(var(--safe-t) + 84px) var(--gutter) calc(var(--safe-b) + 28px);
  background: var(--surface);
  overflow-y: auto;
  overscroll-behavior: contain;
  transform: translateY(-8px);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease), visibility var(--dur);
}

.drawer[data-open="true"] {
  transform: none;
  opacity: 1;
  visibility: visible;
}

.drawer__link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  min-height: 56px;
  padding: 0 4px;
  border-bottom: 1px solid var(--line-soft);
  color: var(--ink-text);
  font-size: 1.0625rem;
  font-weight: var(--fw-bold);
}

.drawer__link[aria-current="true"] {
  color: var(--navy);
  box-shadow: inset 0 -2px 0 var(--ie-yellow);
}

.drawer__cta { margin-top: 18px; }

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


/* --------------------------------------------------------------- buttons -- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: var(--touch);
  padding: 12px 20px;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
  line-height: 1.1;
  text-align: center;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}

.btn__icon { width: 20px; height: 20px; flex: none; }
.btn__arrow { flex: none; transition: transform var(--dur) var(--ease); }

.btn--primary,
.btn--wa {
  background: var(--ie-yellow);
  color: var(--ink-text);
}

.btn--primary:hover,
.btn--wa:hover { background: var(--ie-yellow-deep); }

.btn--primary:hover .btn__arrow,
.btn--ghost:hover .btn__arrow { transform: translateX(4px); }

.btn--ghost {
  background: var(--surface);
  border-color: var(--line);
  color: var(--ink-text);
}

.btn--ghost:hover { border-color: #cfd6de; }

.btn--dark {
  background: var(--ink);
  color: var(--white);
}

.btn:active { transform: translateY(1px); }

.btn--block { width: 100%; }

/* ------------------------------------------------------------------ hero -- */

.hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: linear-gradient(180deg, var(--hero-navy) 0%, var(--hero-navy-2) 100%);
  color: var(--white);
}

.hero__media {
  position: absolute;
  inset: auto 0 0 auto;
  z-index: -1;
  /* the locked phone reference places the photo over the right 670 of its 870px
     band (77%) and lets the scene's left edge fade into the navy band.
     v2.3: the box ratio is declared explicitly, so the photo can never be
     stretched even if a future asset ships a slightly different crop - the
     image always covers the box and the spare pixels are cropped, never
     squeezed (owner brief sec.5). */
  width: 77%;
  max-width: 670px;
  aspect-ratio: 1340 / 806;
  pointer-events: none;
}

.hero__media::after {
  /* CSS scrim only - the photo itself is never distorted or stretched.
     v2.3: the owner's photograph is a daylight yard shot (bright sky, white
     lorries) where the mockup crop was already dark, so the scrim has to carry
     the copy on its own. Two layers: a vertical fade that dissolves the photo's
     top edge into the navy band (the phone photo is bottom-anchored, so its top
     edge would otherwise cut across the paragraph) and a horizontal fade that
     keeps the ink-readable left dark while the lorry, bin and yard stay visible
     on the right. */
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, var(--hero-navy) 0, rgba(2, 15, 31, 0.82) 9%,
                    rgba(2, 15, 31, 0.38) 22%, rgba(2, 15, 31, 0) 38%),
    linear-gradient(90deg, var(--hero-navy) 0, rgba(2, 15, 31, 0.84) 24%,
                    rgba(2, 15, 31, 0.52) 48%, rgba(2, 15, 31, 0.16) 74%,
                    rgba(2, 15, 31, 0) 96%);
}

.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* keeps both lorries, the bin body and the yard in frame (sec.5) */
  object-position: 52% 42%;
}

.hero__inner {
  position: relative;
  display: grid;
  gap: clamp(8px, 1.6vw, 14px);
  padding-block: clamp(18px, 3.4vw, 40px) clamp(20px, 3.6vw, 44px);
  /* the locked phone band is 406px tall at its 870px reference width (46.7vw),
     which is the height the photo needs to sit in the band exactly as designed.
     v2.5 (item 7): the value is the shared --hero-band token (tokens.css) - the
     photo box is now sized from it too, so the bitmap can never be taller than
     the band it sits in (see .hero__media in responsive.css). */
  min-height: var(--hero-band);
}

.hero__title {
  font-size: var(--fs-hero);
  line-height: 1.05;
  /* v2.3 (sec.8-9): a tighter, more deliberate display setting - the two lines
     read as one lock-up and the yellow second line carries the accent */
  letter-spacing: -0.032em;
  color: var(--white);
  /* the phone copy sits on the photo: a soft shadow keeps it legible without
     any glow or outline */
  text-shadow: 0 2px 5px rgba(2, 15, 31, 0.42);
}

.hero__title .accent {
  display: block;
  width: fit-content;
  margin-top: 0.04em;
  letter-spacing: -0.026em;
  color: var(--ie-yellow);
}

.hero__lead {
  max-width: 34ch;
  color: rgba(255, 255, 255, 0.94);
  font-size: var(--fs-lead);
  line-height: 1.55;
  text-shadow: 0 1px 3px rgba(2, 15, 31, 0.4);
}

/* --------------------------------------------------- accreditation strip -- */

.accred {
  padding-block: clamp(12px, 1.8vw, 20px);
  background: var(--surface);
}

/* v2.4 (owner brief 2026-09-25, item 2): ONE white card wraps the heading and all
   seven agency logos, exactly as the locked reference shows (web `02` and mobile
   `02`). v2.2 gave every logo its own card, which split the strip into seven
   boxes; the logos are now separated by the reference's own hairlines
   (`.accred__item + .accred__item`, >=768px). */
.accred__card {
  padding: clamp(8px, 1.6vw, 16px) clamp(6px, 1.4vw, 14px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
}

.accred__title {
  text-align: center;
  color: var(--navy);
  font-size: var(--fs-eyebrow);
  font-weight: var(--fw-bold);
}

.accred__list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(64px, 1fr));
  align-items: center;
  gap: clamp(8px, 1.8vw, 22px);
  margin-top: clamp(8px, 1.4vw, 14px);
}

.accred__item {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  /* no card chrome of its own any more - the seven logos live in .accred__card */
  padding-inline: clamp(2px, 0.6vw, 8px);
}

.accred__item img {
  width: auto;
  max-width: 100%;
  height: clamp(34px, 6.6vw, 50px);
  object-fit: contain;
}

/* --------------------------------------------------------------- features -- */

/* v2.5 (owner brief 2026-09-25, item 6): the phone/tablet benefit strip is four
   premium mini-cards instead of a bare icon row - a white card with the page's
   hairline and a soft elevation, a chip behind the glyph and a brighter label.
   Same four locked labels, same icon assets.
   v2.6 (owner brief 2026-09-25, item 6): the glyphs were the weak part - each
   chip asset carries ~36% white margin around its own pale circle, so at the old
   44px the baked circle rendered 12px and the CSS pill did all the visual work.
   The chip is now drawn big enough for the asset's own circle to be the icon
   (35-53px) and the CSS pill is gone, so the icon itself is the focal point. */
.features { background: var(--surface); }

.features__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(8px, 1.6vw, 14px);
  text-align: center;
}

.features__item {
  display: grid;
  gap: 10px;
  justify-items: center;
  align-content: start;
  padding: 14px 10px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}

/* a gentle lift only - the strip stays calm, it never bounces or glows */
.features__item:hover {
  border-color: rgba(0, 27, 77, 0.14);
  box-shadow: 0 2px 4px rgba(15, 23, 42, 0.05), 0 18px 32px -22px rgba(15, 23, 42, 0.42);
  transform: translateY(-2px);
}

/* no seat of its own any more: the chip asset already carries the pale circle,
   and the white margin around it is invisible on the card's white ground */
.features__disc {
  display: block;
  width: auto;
  height: auto;
  background: none;
  box-shadow: none;
}

.features__icon {
  /* 126-190px of chip = a 35-53px pale circle at every width */
  width: clamp(126px, 36vw, 190px);
  height: auto;
}

.features__label {
  color: var(--navy);
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
  line-height: 1.3;
  max-width: 16ch;
}

/* ---------------------------------------------------------------- pricing -- */

.pricing { background: var(--surface); }

.pricing__grid {
  display: grid;
  gap: var(--gap-card);
  /* v2.6 micro-fix: the heading above is visually hidden, so this grid opens the
     section - its old --gap-block lead-in margin is gone. */
  margin-top: 0;
}

.price-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gap-block);
  padding: clamp(12px, 1.8vw, 16px);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}

.price-card__title {
  font-size: var(--fs-h3);
  color: var(--ink-text);
}

.price-card__subtitle {
  margin-top: 2px;
  color: var(--ink-text);
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.price-card__details {
  display: grid;
  gap: var(--gap-block);
  align-content: start;
}

.price-card__desc {
  max-width: 32ch;
  color: var(--navy);
  font-size: var(--fs-body);
  line-height: 1.45;
}

/* v2.6 (owner brief 2026-09-25, item 3): the bin visual is a framed box whose
   top band is reserved for the three dimension call-outs on phones/tablets.
   The frame's ratio is the photo's own ratio plus that band (746x348 + 104 =
   746x452, 762x357 + 104 = 762x461), so the photo keeps its size and the
   call-outs never overlap the bin. From 1024px up the frame collapses back to
   the plain picture box: the card bitmap there already carries the design's
   own baked lines (responsive.css). */
.price-card__visual {
  position: relative;
  align-self: center;
  justify-self: center;
  width: min(100%, 320px);
}

.price-card__visual--2ft { aspect-ratio: 746 / 452; }
.price-card__visual--4ft { aspect-ratio: 762 / 461; }

.price-card__visual > picture {
  position: absolute;
  inset: auto 0 0 0;
}

.price-card__visual img { width: 100%; height: auto; }

/* the call-out layer: real vectors + real text, so the labels stay crisp at any
   device pixel ratio (a scaled-up bitmap would not) */
.bin-dims {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

.bin-dims__lines line {
  stroke: var(--ie-yellow-deep);
  stroke-width: 3.5;
  stroke-linecap: round;
}

.bin-dims__head path { fill: var(--ie-yellow-deep); }

.bin-dims__labels text {
  fill: var(--ink-text);
  font-family: var(--font-sans);
  font-size: 29px;
  font-weight: var(--fw-black);
  letter-spacing: -0.01em;
}

.price-card__price {
  color: var(--ink-text);
  font-family: var(--font-display);
  font-size: var(--fs-price);
  font-weight: var(--fw-black);
  line-height: 1;
  letter-spacing: -0.02em;
}

/* --------------------------------------------------------- icon utilities -- */

.icon-wa {
  display: inline-block;
  flex: none;
  width: 20px;
  height: 20px;
  background-color: currentColor;
  -webkit-mask: url("../assets/icons/wa.svg") center / contain no-repeat;
  mask: url("../assets/icons/wa.svg") center / contain no-repeat;
}

/* ------------------------------------------------------------- industries -- */

.industries { background: var(--surface); }

.industries__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gap-card);
  /* v2.6 micro-fix: as with .pricing__grid - the "Perkhidmatan" heading above is
     visually hidden, so the six cards open the section. */
  margin-top: 0;
}

.industry-card {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr);
  overflow: hidden;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
}

.industry-card__media { position: relative; }

/* `display: block` matters: an inline photo sat on the text baseline, leaving a
   ~4px white gap under the picture, and it pushed the media box's bottom edge
   (which is where the disc is anchored) below the photo's real edge. */
.industry-card__media img {
  display: block;
  width: 100%;
  height: auto;
}

/* sec.6: the photo box of every card is the box of its locked crop. The `width`
   /`height` attributes describe the desktop crop, so without this the taller
   phone/tablet crop (<1024px) would load into a box reserved for the flatter
   desktop one and shift the rows below it. */
.industry-card:nth-child(1) .industry-card__media img { aspect-ratio: 521 / 179; }
.industry-card:nth-child(2) .industry-card__media img { aspect-ratio: 517 / 195; }
.industry-card:nth-child(3) .industry-card__media img { aspect-ratio: 522 / 193; }
.industry-card:nth-child(4) .industry-card__media img { aspect-ratio: 521 / 169; }
.industry-card:nth-child(5) .industry-card__media img { aspect-ratio: 517 / 176; }
.industry-card:nth-child(6) .industry-card__media img { aspect-ratio: 522 / 173; }

.industry-card__body {
  padding: clamp(8px, 1.4vw, 12px) clamp(10px, 1.6vw, 14px) clamp(10px, 1.8vw, 14px);
}

/* The locked card pairs the yellow disc with the card title. The disc is its own
   asset (cropped from the design's strip) because the title must stay real
   HTML - the bitmap used to carry both, which is what rendered every title
   twice. The mobile reference has no disc, so it is hidden below 1024px; from
   1024px up it is positioned against the media box (see responsive.css) so it
   straddles the photo's bottom edge exactly as designed. */
.industry-card__head {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.industry-card__icon {
  display: none;
  flex: none;
  width: 53px;
  height: auto;
}

.industry-card__title {
  font-size: clamp(0.75rem, 0.7rem + 0.45vw, 0.8125rem);
  color: var(--ink-text);
  min-width: 0;
}

.industry-card__desc {
  margin-top: 4px;
  max-width: none;
  color: var(--navy);
  font-size: clamp(0.625rem, 0.58rem + 0.28vw, 0.6875rem);
  line-height: 1.4;
}

/* --------------------------------------------------------------- coverage -- */

/* Mobile scope note (sec.12): the locked mobile reference has no coverage
   section and no footer, so both used to be opt-in from 1024px up.
   v2.6 (owner brief 2026-09-25, item 4): the owner wants the phone page to end
   like the desktop one - a real footer with the same brand sticker, phone,
   domain and service area - and the "Tentang Kami" menu entry points at this
   section, so a hidden section would leave a dead anchor on phones. Both are now
   part of the phone page: the coverage block stacks (heading, map, service-area
   card) and the footer runs as one column. */
.coverage { display: block; background: var(--surface); }

.coverage__inner {
  display: grid;
  gap: clamp(16px, 2.6vw, 28px);
}

.coverage__cta { margin-top: var(--gap-block); }

.coverage__map {
  position: relative;
  display: grid;
  gap: clamp(12px, 3vw, 18px);
}

.coverage__map > img {
  width: 100%;
  height: auto;
  border-radius: var(--r-md);
  align-self: center;
}

/* HTML rebuild of the service-area card (the baked twin is cropped out of
   coverage-map.png so every place name stays selectable + indexable) */
.coverage__card {
  align-self: center;
  min-width: 0;
  padding: clamp(10px, 1.4vw, 16px);
  background: var(--surface);
  border-radius: var(--r-md);
  box-shadow: 0 16px 40px -22px rgba(2, 15, 31, 0.45);
}

.coverage__card-title {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--ink-text);
  font-size: var(--fs-small);
  font-weight: var(--fw-bold);
}

.coverage__card-title::before {
  content: "";
  flex: none;
  width: 18px;
  height: 18px;
  border-radius: 50% 50% 50% 0;
  background: var(--ie-yellow);
  transform: rotate(-45deg);
}

.coverage__list {
  display: grid;
  gap: 5px;
  margin-top: 8px;
}

/* ---------------------------------------------------------------- footer -- */

/* v2.6 (owner brief 2026-09-25, item 4): the footer is part of every breakpoint
   now - phones get the same brand sticker, phone number, domain and service area
   as desktops, stacked in one readable column at the end of the page. */
.site-footer {
  display: block;
  background: var(--ink);
  color: rgba(255, 255, 255, 0.82);
  padding-block: clamp(18px, 5vw, 24px);
  padding-bottom: calc(clamp(18px, 5vw, 24px) + var(--safe-b));
}

.site-footer__inner {
  display: grid;
  gap: clamp(12px, 3.4vw, 18px);
}

.site-footer__brand img {
  width: clamp(184px, 56vw, 240px);
  height: auto;
}

.site-footer__contact {
  display: grid;
  gap: 2px;
}

.contact-item {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  /* phone/tablet footer links are real touch targets (>=44px) */
  min-height: var(--touch);
  color: var(--white);
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
}

.contact-item img {
  width: 26px;
  height: 26px;
  flex: none;
}

.contact-item:hover { color: var(--ie-yellow); }

.site-footer__legal {
  margin-top: 10px;
  font-size: var(--fs-small);
  color: rgba(255, 255, 255, 0.68);
}

.site-footer .check { color: rgba(255, 255, 255, 0.82); }
.site-footer .check__mark { width: 18px; height: 18px; font-size: 11px; }


.price-card__checks {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 6px;
}

.check {
  display: grid;
  grid-template-columns: 18px minmax(0, 1fr);
  align-items: start;
  gap: 7px;
  color: var(--navy);
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  line-height: 1.3;
}

.check__mark {
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  border-radius: 50%;
  background: var(--ie-yellow);
  color: var(--ink);
  font-size: 10px;
  font-weight: var(--fw-black);
  line-height: 1;
}


/* v2.3 (sec.10-13): hero copy furniture. The eyebrow becomes a badge (yellow
   rule + tracked uppercase label), the CTAs get a premium pill finish and the
   phone scrim keeps the whole block legible over the owner's daylight photo. */
.hero .eyebrow {
  justify-self: start;
  gap: 9px;
  padding: 6px 13px 6px 10px;
  border: 1px solid rgba(255, 255, 255, 0.24);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.11);
  color: rgba(255, 255, 255, 0.96);
  font-weight: var(--fw-black);
  letter-spacing: 0.13em;
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
}

.hero .eyebrow__dash { width: 22px; height: 2.5px; }

.hero__cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
}

.hero__cta .btn {
  gap: 9px;
  letter-spacing: -0.006em;
  box-shadow: var(--shadow-pill);
}

.hero__cta .btn--primary { inline-size: min(100%, 349px); }

.hero__cta .btn--primary:hover,
.hero__cta .btn--wa:hover {
  transform: translateY(-1px);
  box-shadow: 0 14px 28px -10px rgba(245, 196, 0, 0.95);
}

.hero__cta .btn--ghost {
  border-color: rgba(2, 15, 31, 0.1);
  box-shadow: 0 10px 24px -20px rgba(2, 15, 31, 0.6);
}

.hero__cta .btn--ghost:hover {
  border-color: rgba(2, 15, 31, 0.2);
  transform: translateY(-1px);
}

/* benefit row - desktop only inside the hero (mobile shows it as its own
   section, matching the locked mobile reference).
   v2.6 (owner brief 2026-09-25, item 6): the owner rejected the v2.5 shape - a
   white card of four small 30px discs with the label beside each one. The row is
   now the design's own idiom, done properly: nothing but the four IE-yellow
   discs (48px, +60% on the old 30px) with their label centred underneath, wide
   column gaps and no card chrome, so the icons are the focus and the strip has
   air. Copy, order and assets are untouched; the row lives on the hero's navy
   band (desktop, responsive.css). */
.benefits { display: none; }

.benefits__item {
  display: grid;
  justify-items: center;
  gap: 10px;
  min-width: 0;
  text-align: center;
  border-radius: var(--r-sm);
}

/* no pale seat behind the disc any more: the locked asset is the disc */
.benefits__disc {
  display: block;
  width: auto;
  height: auto;
  background: none;
  box-shadow: none;
}

.benefits__icon { width: 48px; height: 48px; }

.benefits__label {
  color: var(--navy);
  font-size: 0.6875rem;
  font-weight: var(--fw-bold);
  letter-spacing: -0.004em;
  line-height: 1.24;
  max-width: 13ch;
  min-width: 0;
}
