@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@500;600;700&family=Inter:wght@400;500;600&display=swap');

/* ==========================================================================
   Aditi IT Software Solutions — Services page
   Built against references/branding-aditi/, NOT the current live site.

   PASTE THIS WHOLE FILE into Divi > Theme Options > General > Custom CSS.
   The @import above must stay on line 1 or the brand fonts will not load.
   --------------------------------------------------------------------------
   Palette      Navy #1D3461, Cyan #00B4D8 (guidelines/03-colors.md)
   Type         Montserrat headings, Inter body (guidelines/04-typography.md)
   Devices      Cyan accent bar, cyan underline rule, navy panel, dot grid
                (export/brand-guide.css + the logo's dot halo, which
                06-visual-style.md names as the only decorative device)
   Constraints  No gradients, no glassmorphism, no glows, no neon.
                Navy under 30% of page area. Cyan 10-20%.
                Never white text on cyan (fails AA at 2.7:1).
   Scope        Everything under .aditi. No container width: the Divi row
                already sets it.
   ========================================================================== */

.aditi {
  --navy:       #1D3461;
  --navy-deep:  #16274A;
  --cyan:       #00B4D8;
  --cyan-deep:  #0092AF;
  --black:      #1A1A2E;
  --mid:        #4A4A6A;
  --border:     #D4D4E0;
  --bg-light:   #F8F8FC;
  --white:      #FFFFFF;

  --head: 'Montserrat', Arial, Helvetica, sans-serif;
  --body: 'Inter', Arial, Helvetica, sans-serif;

  font-family: var(--body);
  font-size: 16px;
  line-height: 1.6;
  color: var(--black);
  -webkit-font-smoothing: antialiased;

  /* Fills whatever width the Divi row gives it. Set the row to
     Width 100% / Max Width 1200px. No width is imposed here. */
  width: 100%;
}

.aditi *, .aditi *::before, .aditi *::after { box-sizing: border-box; }

/* --------------------------------------------------------------------------
   Divi cascade guards. IMPORTANT, do not simplify these selectors.

   Divi's Theme Customizer emits `#et-boc .et-l h1..h6 { color: <your blue> }`.
   That is an ID-level selector, so it beats ANY plain class rule of ours no
   matter where it sits in the file. Every heading colour we set therefore
   needs a matching `#et-boc .et-l` counterpart, or Divi's blue wins inside the
   builder and headings on dark panels render blue-on-navy and unreadable.
   -------------------------------------------------------------------------- */
.aditi h1, .aditi h2, .aditi h3, .aditi h4,
#et-boc .et-l .aditi h1, #et-boc .et-l .aditi h2,
#et-boc .et-l .aditi h3, #et-boc .et-l .aditi h4 {
  font-family: var(--head);
  color: var(--navy);
  margin: 0 0 12px;
  padding-bottom: 0;
}

.aditi h1 { font-size: 40px; font-weight: 700; line-height: 1.15; letter-spacing: -.02em; }
.aditi h2 { font-size: 28px; font-weight: 600; line-height: 1.3;  letter-spacing: -.02em; }
.aditi h3 { font-size: 20px; font-weight: 600; line-height: 1.4; }
.aditi h4 { font-size: 17px; font-weight: 600; line-height: 1.4; color: var(--black); }

.aditi p { margin: 0 0 14px; padding-bottom: 0; }
.aditi p:last-child { margin-bottom: 0; }
.aditi ul { margin: 0; padding: 0; list-style: none; }
.aditi li { margin: 0; }

.aditi a { color: var(--cyan-deep); text-decoration: none; transition: color .18s ease; }
.aditi a:hover { color: var(--navy); }
.aditi a:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; }

.aditi strong { font-weight: 600; color: var(--navy); }

/* ---------- rhythm. No horizontal padding: the Divi row supplies it ------ */

.aditi .sec { padding: 64px 0; }
.aditi .sec:first-child { padding-top: 0; }
.aditi .sec:last-child { padding-bottom: 0; }
.aditi .sec + .sec { border-top: 1px solid var(--border); }
.aditi .sec--plain + .sec--plain { border-top: 0; }

/* Full-bleed panels break the border rule, so cancel it around them */
.aditi .sec--panel { padding: 0; }
.aditi .sec--panel + .sec, .aditi .sec--panel { border-top: 0; }

.aditi .head { max-width: 44em; margin-bottom: 36px; }
/* A heading with an action beside it. The button sits at the right of the h2
   line, above the paragraph, and drops under the heading on a narrow screen
   rather than squeezing the title.

   justify-content lives HERE, on the flex PARENT. Written on the button
   itself it does nothing: justify-content aligns a container children, it
   does not align the element it is set on. */
.aditi .head-row {
  display: flex; flex-wrap: wrap;
  align-items: center; justify-content: space-between;
  gap: 12px 28px;
  margin-bottom: 10px;
}
.aditi .head-row h2, #et-boc .et-l .aditi .head-row h2 { margin-bottom: 0; }
.aditi .head-row .btn { flex: 0 0 auto; }
/* .head is capped at 44em so paragraphs do not run to unreadable line lengths.
   That cap would also stop the button short of the content edge, leaving a gap
   that reads as a mistake rather than as alignment. So a head that contains a
   head-row drops the cap, and the cap moves to the paragraph, which is the
   only child that needed it. Falls back to the capped layout where :has() is
   unsupported, which is still correct, just narrower. */
.aditi .head:has(.head-row) { max-width: none; }
.aditi .head:has(.head-row) > p { max-width: 44em; }
.aditi .head p { font-size: 18px; line-height: 1.7; color: var(--mid); margin-bottom: 0; }
.aditi .head h2 { margin-bottom: 10px; }

/* Uppercase eyebrow label */
.aditi .kicker {
  display: block;
  font-family: var(--head);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--cyan-deep);
  margin-bottom: 14px;
}

/* Cyan underline rule under a heading. From brand-guide.css h1. */
.aditi .ruled { padding-bottom: 12px; border-bottom: 3px solid var(--cyan); display: inline-block; }

/* Cyan accent bar. From brand-guide.css .cover-accent. */
.aditi .bar { width: 6px; height: 64px; border-radius: 3px; background: var(--cyan); }

.aditi .lead { font-size: 18px; line-height: 1.7; color: var(--mid); }

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

/* Divi's customizer sets `body .et_pb_button { border-radius: 50px }` and the
   theme rounds anchors broadly, which turns these into pills. 06-visual-style.md
   calls for slightly rounded corners, not pill shapes, so pin the radius with
   the ID-level guard. */
.aditi .btn,
#et-boc .et-l .aditi .btn {
  display: inline-block;
  font-family: var(--head);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  padding: 15px 28px;
  border: 2px solid transparent;
  border-radius: 4px;
  text-align: center;
  transition: background .18s ease, color .18s ease, border-color .18s ease;
}
/* Every modifier needs the ID-level guard too. Divi's customizer sets
   `body .et_pb_button { border-color: rgba(255,255,255,0) }`, i.e. TRANSPARENT,
   which erases the outline on any button that has no background fill. */
.aditi .btn--primary,
#et-boc .et-l .aditi .btn--primary { background: var(--navy); border-color: var(--navy); color: var(--white); }
.aditi .btn--primary:hover,
#et-boc .et-l .aditi .btn--primary:hover { background: var(--navy-deep); border-color: var(--navy-deep); color: var(--white); }

/* Outline button: navy border always visible, fills navy on hover. */
.aditi .btn--ghost,
#et-boc .et-l .aditi .btn--ghost { background: transparent; border-color: var(--navy); color: var(--navy); }
.aditi .btn--ghost:hover,
#et-boc .et-l .aditi .btn--ghost:hover { background: var(--navy); border-color: var(--navy); color: var(--white); }

/* On navy: white fill, navy label. Never white-on-cyan. */
.aditi .btn--onnavy,
#et-boc .et-l .aditi .btn--onnavy { background: var(--white); border-color: var(--white); color: var(--navy); }
.aditi .btn--onnavy:hover,
#et-boc .et-l .aditi .btn--onnavy:hover { background: var(--cyan); border-color: var(--cyan); color: var(--navy); }

/* Outline button on navy: the border must be white, not blue, to be visible. */
.aditi .btn--onnavy-line,
#et-boc .et-l .aditi .btn--onnavy-line { background: transparent; border-color: rgba(255,255,255,.55); color: var(--white); }
.aditi .btn--onnavy-line:hover,
#et-boc .et-l .aditi .btn--onnavy-line:hover { border-color: var(--white); background: rgba(255,255,255,.10); color: var(--white); }

.aditi .btns { display: flex; flex-wrap: wrap; gap: 12px; }

.aditi .textlink { font-family: var(--head); font-size: 14px; font-weight: 600; }
.aditi .textlink::after { content: ' \2192'; }

/* ---------- panels + dot grid --------------------------------------------- */
/* The dot grid is the logo's halo motif. 06-visual-style.md permits it as the
   only decorative device. Drawn with radial-gradient, but the result is a dot
   pattern, not a gradient fill. One declaration, recoloured per panel. */

.aditi .dots {
  background-image: radial-gradient(var(--dot) 1.5px, transparent 1.5px);
  background-size: 22px 22px;
  background-position: 0 0;
}

/* Light panel. The default surface: white is the brand's primary ground and
   navy is reserved for anchors (03-colors.md, 06-visual-style.md). */
.aditi .panel-light {
  --dot: rgba(29, 52, 97, .085);
  position: relative;
  overflow: hidden;
  background-color: var(--bg-light);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 56px 44px;
}
.aditi .panel-light .bar { margin-bottom: 26px; }

/* Navy panel. Used once, for the closing CTA, keeping navy well under the
   30% page-area limit. */
.aditi .navy {
  --dot: rgba(255, 255, 255, .10);
  position: relative;
  overflow: hidden;
  background-color: var(--navy);
  color: var(--white);
  padding: 56px 44px;
  border-radius: 6px;
}
.aditi .navy p { color: rgba(255,255,255,.82); }
.aditi .navy .kicker { color: var(--cyan); }
.aditi .navy .bar { margin-bottom: 26px; }

/* Heading colour on the navy panel needs the ID-level guard, see the note at
   the top of this file. Without the #et-boc pair, Divi renders these blue. */
.aditi .navy h1, .aditi .navy h2, .aditi .navy h3, .aditi .navy h4,
#et-boc .et-l .aditi .navy h1, #et-boc .et-l .aditi .navy h2,
#et-boc .et-l .aditi .navy h3, #et-boc .et-l .aditi .navy h4 { color: var(--white); }

/* Sized for a 1200px row. `ch` caps line length, not the block: the panel
   itself always fills 100% of whatever width the Divi row gives it. */
/* DEVIATION from guidelines/04-typography.md, which specifies H1 at 36px.
   36px reads undersized on a 1200px row, so the hero scales up to 50px on wide
   viewports, passes through the documented 36px at about 880px, and eases down
   on phones. Every other heading stays exactly on the documented scale.
   Replace with `font-size: 36px` if you want strict compliance. */
.aditi .hero h1 { max-width: 22ch; margin-bottom: 22px; font-size: clamp(30px, 4.1vw, 50px); line-height: 1.1; }
.aditi .hero .lead { font-size: 20px; max-width: 62ch; margin-bottom: 32px; }
.aditi .hero .btns { margin-bottom: 36px; }

/* Hero with an image beside the copy. */
/* The accent bar and eyebrow sit ABOVE this grid, so both columns begin at the
   same line and the image frame is level with the headline by construction.
   The previous version pushed the image down with a hand-tuned margin, which
   only held while the bar and eyebrow kept their exact sizes. */
.aditi .hero-split {
  display: grid;
  grid-template-columns: 1.08fr .92fr;
  gap: 44px;
  /* start, not stretch. Stretching made the frame as tall as the whole copy
     column, which left a large empty area above the figure. */
  align-items: start;
}

/* A frame for the portrait. The source is a cut-out on a transparent
   background, so unframed its lower edge just stops in mid-air and reads as a
   pasted cut-out. Sitting it flush to the bottom of a panel makes that edge the
   base of the frame instead, so the figure looks placed rather than cropped. */
.aditi .hero-media {
  position: relative;
  display: flex;
  align-items: flex-end;      /* figure stands on the base of the frame */
  justify-content: center;
  /* Small gap above so the head is not jammed against the edge, none below so
     the figure meets the floor. The frame height follows the image. */
  padding: 18px 20px 0;
  background: var(--white);
  border: 1px solid var(--border);
  border-bottom: 3px solid var(--cyan);
  border-radius: 8px;
  overflow: hidden;
}
.aditi .hero-media img {
  display: block;
  width: 100%;
  height: auto;
  /* The source is only 349x377. Rendering it wider upscales and softens it. */
  max-width: 349px;
  margin: 0;
}

/* Logo walls. These are single wide images rather than individual logo files,
   so they are capped and centred and never allowed to overflow the row. */
.aditi .logowall { display: flex; flex-direction: column; gap: 26px; }
.aditi .logowall img {
  display: block;
  width: 100%;
  height: auto;
  max-width: 1100px;
  margin: 0 auto;
}

/* A grid, not flex-wrap. With flex, items of different lengths pack onto a row
   wherever they happen to fit, which put two items on one line and one on the
   next and read as broken. Grid columns keep every item on its own track and
   the rows aligned however long the labels are.

   auto-fit adapts to the container: the homepage list sits in a half-width
   column and lands on two columns, the full-width service page heroes on
   three. */
.aditi .hero-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 13px 28px;
  padding-top: 24px;
  border-top: 1px solid var(--border);
  font-size: 14px; color: var(--mid);
}
.aditi .hero-facts li { display: flex; align-items: flex-start; gap: 9px; line-height: 1.45; }
.aditi .hero-facts svg { color: var(--cyan-deep); flex: 0 0 auto; margin-top: 2px; }

/* ---------- guarantee ----------------------------------------------------- */

.aditi .guarantee {
  background: var(--bg-light);
  border: 1px solid var(--border);
  border-left: 4px solid var(--cyan);
  border-radius: 0 6px 6px 0;
  padding: 32px 36px;
}
.aditi .guarantee .kicker { margin-bottom: 10px; }
.aditi .guarantee q {
  display: block;
  font-family: var(--head);
  font-size: 20px;
  font-weight: 500;
  line-height: 1.55;
  color: var(--navy);
  quotes: none;
}
.aditi .guarantee q::before, .aditi .guarantee q::after { content: ''; }
.aditi .guarantee .sig { font-size: 14px; color: var(--mid); margin-top: 16px; }

/* ---------- lanes (the three services) ------------------------------------ */

.aditi .lanes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }

.aditi .lane {
  display: flex; flex-direction: column;
  background: var(--white);
  border: 1px solid var(--border);
  border-top: 3px solid var(--cyan);
  border-radius: 6px;
  padding: 30px 28px;
  transition: border-color .18s ease, transform .18s ease;
}
.aditi .lane:hover { border-color: var(--navy); border-top-color: var(--cyan); transform: translateY(-2px); }

.aditi .lane-icon {
  width: 48px; height: 48px;
  display: flex; align-items: center; justify-content: center;
  background: var(--bg-light);
  border-radius: 6px;
  color: var(--navy);
  margin-bottom: 20px;
}
.aditi .lane h3 { margin-bottom: 10px; }
.aditi .lane .lane-line { font-size: 15px; color: var(--mid); margin-bottom: 16px; }
.aditi .lane p { font-size: 15px; line-height: 1.65; color: var(--black); }
.aditi .lane .lane-foot {
  margin-top: auto; padding-top: 18px;
  border-top: 1px solid var(--border);
  font-size: 13px; color: var(--mid);
}
/* Align the DELIVERED block across all three cards.
   `margin-top: auto` alone only bottom-aligns the footer, so when one card's
   footer copy runs to fewer lines its divider sits at a different height.
   Subgrid makes the three cards share one set of rows, so icon, title,
   strapline, body and footer each line up. The 1fr row is the body, which
   absorbs the slack. Falls back to flex where subgrid is unsupported.

   MUST stay after the `.aditi .lane { display: flex }` rule above. @supports
   adds no specificity, so if this block sits earlier the later `display: flex`
   overrides `display: grid` and the whole thing silently does nothing. */
/* Opt-out: `.lanes--home` cards have six children, not five, so the fixed
   five-row track list below would push the last one into an implicit row and
   break the card. Those cards fall back to flex. */
@supports (grid-template-rows: subgrid) {
  .aditi .lanes:not(.lanes--home) {
    grid-template-rows: auto auto auto 1fr auto;
    /* A subgrid inherits the parent's gap, which would push 24px between every
       element inside each card. There is one row of cards, so the parent's
       row-gap is doing no work. Spacing stays on the child margins. */
    row-gap: 0;
    column-gap: 24px;
  }
  .aditi .lanes:not(.lanes--home) > .lane {
    display: grid;
    grid-row: span 5;
    grid-template-rows: subgrid;
    row-gap: 0;
  }
  .aditi .lanes:not(.lanes--home) > .lane .lane-foot { margin-top: 0; }
}

.aditi .lane .lane-foot b { display: block; font-family: var(--head); font-size: 11px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase; color: var(--mid); margin-bottom: 5px; }

/* ---------- tag blocks: domains and technologies ---------------------------
   Sixteen domains and fifteen technologies. As label-and-description rows this
   ran to half a screen and stopped being scannable, so each entry is a tag and
   the whole set reads at a glance. Each block runs full width rather than
   sitting in a half column, which would force the tags into a narrow ragged
   stack. */

.aditi .tagblocks { display: flex; flex-direction: column; gap: 30px; margin-top: 36px; }

.aditi .tagblock-label {
  display: flex;
  align-items: center;
  gap: 10px;
  font-family: var(--head);
  font-size: 11.5px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--mid);
  margin: 0 0 16px;
  padding-top: 20px;
  border-top: 1px solid var(--border);
}
/* The count doubles as evidence for the stat strip below. */
.aditi .tagblock-label span {
  font-size: 11px;
  color: var(--cyan-deep);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 2px 9px;
  letter-spacing: .04em;
}

.aditi .taglist { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.aditi .taglist li,
#et-boc .et-l .aditi .taglist li {
  margin: 0;
  font-family: var(--body);
  font-size: 13.5px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--navy);
  background: var(--bg-light);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 7px 15px;
  white-space: nowrap;
}

.aditi .lanes--home .lane { padding: 28px 26px; }
.aditi .lanes--home .lane h3 { margin-bottom: 6px; font-size: 19px; }
.aditi .lanes--home .lane .lane-line { margin-bottom: 14px; color: var(--mid); font-size: 15px; }
.aditi .lanes--home .lane p { font-size: 15px; line-height: 1.65; }
.aditi .lanes--home .lane .lane-foot { margin-top: auto; padding-top: 22px; }

/* Four children per card here (title, strapline, body, action), so a four-row
   subgrid keeps the three cards aligned row for row. Kept separate from the
   five-row services rule above, which has an icon as its first child. */
@supports (grid-template-rows: subgrid) {
  .aditi .lanes--home { grid-template-rows: auto auto 1fr auto; row-gap: 0; column-gap: 24px; }
  .aditi .lanes--home > .lane {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    row-gap: 0;
  }
  .aditi .lanes--home > .lane .lane-foot { margin-top: 0; }
}


/* ---------- stat strip ------------------------------------------------------ */
/* One bordered strip divided into equal cells. The 1px grid gap over a border
   coloured background draws the dividers, so there is no per-cell border to
   double up at the joins. Cyan top edge ties it to the cards above. */

.aditi .stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-top: 3px solid var(--cyan);
  border-radius: 6px;
  overflow: hidden;
}
.aditi .stats li { background: var(--white); padding: 28px 26px; }

.aditi .stats b,
#et-boc .et-l .aditi .stats b {
  display: block;
  font-family: var(--head);
  font-size: 36px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -.02em;
  color: var(--navy);
  font-variant-numeric: tabular-nums;
}
.aditi .stats span {
  display: block;
  font-family: var(--head);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--mid);
  margin-top: 9px;
}

/* ---------- facepile --------------------------------------------------------- */
/* Overlapping circles, same 52px treatment as the Client Speak avatars. The
   white ring is what separates one face from the next where they overlap. */

.aditi .facepile { display: flex; align-items: center; flex: 0 0 auto; }
.aditi .facepile img,
#et-boc .et-l .aditi .facepile img {
  display: block;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  object-fit: cover;
  background: var(--white);
  border: 2px solid var(--white);
  margin-left: -12px;
  max-width: none;
}
.aditi .facepile img:first-child { margin-left: 0; }

/* ---------- role / credential cards ----------------------------------------- */

/* Named person card on the About page: initials avatar, then name and title.
   .who and .what are spans here rather than paragraphs, so they need the block
   display and sizing the .proof-item paragraph versions carry. */
.aditi .person-head { display: flex; align-items: center; gap: 14px; margin-bottom: 16px; }
.aditi .person-head .ini { flex: 0 0 auto; display: block; line-height: 0; }
.aditi .person-head .ini svg { display: block; width: 52px; height: 52px; }
.aditi .person-head .who,
#et-boc .et-l .aditi .person-head .who {
  display: block;
  font-family: var(--head);
  font-size: 16px; font-weight: 600;
  color: var(--navy);
  line-height: 1.3;
  margin: 0 0 3px;
}
.aditi .person-head .what { display: block; font-size: 13px; color: var(--mid); line-height: 1.4; margin: 0; }

.aditi .trust-head { display: flex; align-items: center; gap: 12px; margin-bottom: 10px; }
.aditi .trust-head h4 { margin: 0; }
.aditi .trust-head .ini { flex: 0 0 auto; display: block; line-height: 0; }
.aditi .trust-head .ini svg { display: block; width: 44px; height: 44px; }
/* Used where a claim is made about a role rather than a named person, which is
   what the homepage requires (naming_policy: assert the role, never a person). */

.aditi .trust-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; }
.aditi .trust {
  background: var(--bg-light);
  border: 1px solid var(--border);
  border-left: 3px solid var(--cyan);
  border-radius: 0 6px 6px 0;
  padding: 24px 26px;
}
.aditi .trust h4,
#et-boc .et-l .aditi .trust h4 {
  font-size: 16px;
  color: var(--navy);
  margin-bottom: 8px;
}
.aditi .trust p { font-size: 15px; line-height: 1.65; color: var(--mid); margin: 0; }

/* ---------- fears (2x2) ---------------------------------------------------- */

.aditi .fears { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.aditi .fear {
  display: grid; grid-template-columns: 40px 1fr; gap: 18px;
  padding: 26px 28px;
  background: var(--bg-light);
  border-radius: 6px;
}
.aditi .fear svg { color: var(--cyan-deep); margin-top: 2px; }
.aditi .fear h4 { margin-bottom: 6px; }
.aditi .fear p { font-size: 15px; line-height: 1.65; color: var(--mid); margin-bottom: 0; }

/* ---------- phases --------------------------------------------------------- */

.aditi .phases { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.aditi .phase { padding-top: 20px; border-top: 3px solid var(--navy); }
.aditi .phase:last-child { border-top-color: var(--cyan); }
.aditi .phase .n {
  font-family: var(--head); font-size: 12px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase; color: var(--cyan-deep);
  display: block; margin-bottom: 10px;
}
.aditi .phase h3 { font-size: 18px; margin-bottom: 8px; }
.aditi .phase p { font-size: 15px; line-height: 1.65; color: var(--mid); }

/* ---------- proof ---------------------------------------------------------- */

.aditi .proof { display: grid; grid-template-columns: repeat(2, 1fr); gap: 22px; }
/* Fifth item in a two-column grid: span the row so it does not leave a ragged
   empty cell beside it. */
.aditi .proof-item--wide { grid-column: 1 / -1; }
.aditi .proof-item {
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 24px 26px;
}
.aditi .proof-item .who {
  font-family: var(--head); font-size: 16px; font-weight: 600;
  color: var(--navy); margin-bottom: 4px;
}
.aditi .proof-item .what { font-size: 13px; color: var(--mid); margin-bottom: 12px; }
.aditi .proof-item p { font-size: 15px; line-height: 1.6; color: var(--black); margin-bottom: 0; }
.aditi .proof-item .stack {
  display: flex; flex-wrap: wrap; gap: 7px;
  margin-top: 14px; padding-top: 14px; border-top: 1px solid var(--border);
}
/* Technology tags. One rule for every card type: without it the spans render
   as a run-on line of plain text that is genuinely hard to read.

   Deliberately pill-shaped while buttons stay at 4px. The shape carries the
   meaning: rounded rectangle = something you click, pill = a passive label.
   Keeping them visually different stops a tag reading as a dead button. */
.aditi .stack span,
#et-boc .et-l .aditi .stack span {
  display: inline-block;
  font-family: var(--body);
  font-size: 12.5px;
  font-weight: 500;
  line-height: 1.45;
  color: var(--navy);
  background: var(--bg-light);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 5px 13px;
  white-space: nowrap;
}

/* Trailing action band under a grid. Reads as a deliberate closing element
   rather than a leftover strip: one surface, text left, action right, and no
   hairline of its own (the panel edge already separates it). */
.aditi .sec-more {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px 28px;
  margin-top: 24px;
  padding: 26px 30px;
  background: var(--bg-light);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.aditi .sec-more .more-text { flex: 1 1 22em; }
.aditi .sec-more b {
  display: block;
  font-family: var(--head);
  font-size: 16px;
  font-weight: 600;
  color: var(--navy);
  margin-bottom: 3px;
}
.aditi .sec-more p { font-size: 15px; line-height: 1.6; color: var(--mid); margin: 0; }
.aditi .sec-more .btn { flex: 0 0 auto; }

/* ---------- case study list (Tier 1) --------------------------------------- */

/* Two columns: at 20 entries a single stacked column runs to several screens. */
.aditi .cs-list { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; }

.aditi .cs-item {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-left: 4px solid var(--cyan);
  border-radius: 0 6px 6px 0;
  padding: 26px 28px;
  transition: border-color .18s ease;
}
.aditi .cs-item:hover { border-color: var(--navy); border-left-color: var(--cyan); }
.aditi .cs-item .p-client,
#et-boc .et-l .aditi .cs-item .p-client { font-size: 17px; margin-bottom: 6px; }
.aditi .cs-item .cs-meta {
  font-family: var(--head); font-size: 12px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase; color: var(--cyan-deep);
  margin-bottom: 10px;
}
.aditi .cs-item h3 { font-size: 19px; line-height: 1.35; margin-bottom: 9px; }
.aditi .cs-item p { font-size: 15px; line-height: 1.65; color: var(--mid); margin-bottom: 14px; }
.aditi .cs-item .stack {
  display: flex; flex-wrap: wrap; gap: 7px;
  margin-top: auto; padding-top: 13px; border-top: 1px solid var(--border);
}
.aditi .cs-item .cs-action { margin-top: 14px; }

/* ---------- project grid (all delivered work) ------------------------------ */
/* 20 cards show by default; the rest are revealed by the See more button.
   Hiding is done with nth-child rather than a class per card, so the markup
   stays clean and every project remains in the DOM for search and for the
   language models that read this page (GEO, handover section 10A). */

.aditi .pgrid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }
.aditi .pgrid .pcard:nth-child(n+21) { display: none; }
.aditi .pgrid.is-open .pcard:nth-child(n+21) { display: flex; }

.aditi .pcard {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-left: 3px solid var(--cyan);
  border-radius: 0 6px 6px 0;
  padding: 22px 24px;
  transition: border-color .18s ease;
}
.aditi .pcard:hover { border-color: var(--navy); border-left-color: var(--cyan); }

/* The client line is the first thing read, so it carries the most weight. */
.aditi .pcard .p-client,
#et-boc .et-l .aditi .pcard .p-client {
  font-family: var(--head);
  font-size: 15.5px;
  font-weight: 700;
  color: var(--navy);
  line-height: 1.35;
  margin: 0 0 5px;
}
.aditi .pcard .p-meta {
  font-family: var(--head);
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--cyan-deep);
  margin: 0 0 11px;
  line-height: 1.4;
}
.aditi .pcard h3 { font-size: 17px; line-height: 1.4; margin-bottom: 12px; }
.aditi .pcard .stack {
  display: flex; flex-wrap: wrap; gap: 7px;
  margin-top: auto; padding-top: 13px;
  border-top: 1px solid var(--border);
}
.aditi .pcard .p-action { margin-top: 14px; }
.aditi .btn--sm,
#et-boc .et-l .aditi .btn--sm { padding: 10px 18px; font-size: 13.5px; }

.aditi .pmore { margin-top: 26px; text-align: center; }
.aditi .pmore .btn { min-width: 15em; }
.aditi .pnote { font-size: 14px; color: var(--mid); margin-top: 18px; }

/* ---------- delivery history table (Tier 2) -------------------------------- */
/* Divi styles bare tables (borders, striping, cell padding). Reset ours with
   the ID-level guard or Divi's treatment shows through. Pattern follows
   export/brand-guide.css: navy head, alternating bg-light rows. */

.aditi .table-wrap {
  overflow-x: auto;
  border: 1px solid var(--border);
  border-radius: 6px;
  -webkit-overflow-scrolling: touch;
}

.aditi table.dtable,
#et-boc .et-l .aditi table.dtable {
  width: 100%;
  min-width: 720px;
  border-collapse: collapse;
  border: 0;
  margin: 0;
  font-size: 14.5px;
}

.aditi .dtable thead tr,
#et-boc .et-l .aditi .dtable thead tr { background: var(--navy); }

.aditi .dtable thead th,
#et-boc .et-l .aditi .dtable thead th {
  font-family: var(--head);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--white);
  text-align: left;
  padding: 12px 16px;
  border: 0;
  white-space: nowrap;
}

.aditi .dtable tbody td,
#et-boc .et-l .aditi .dtable tbody td {
  padding: 11px 16px;
  border: 0;
  border-bottom: 1px solid var(--border);
  color: var(--black);
  vertical-align: top;
  line-height: 1.5;
}
.aditi .dtable tbody tr:last-child td { border-bottom: 0; }
.aditi .dtable tbody tr:nth-child(even) td { background: var(--bg-light); }

.aditi .dtable .c-client { font-weight: 500; color: var(--navy); min-width: 15em; }
.aditi .dtable .c-named { font-weight: 600; }
.aditi .dtable .c-domain { color: var(--mid); white-space: nowrap; }
.aditi .dtable .c-stack { color: var(--mid); font-size: 13.5px; }

.aditi .table-note { font-size: 14px; color: var(--mid); margin-top: 14px; }

/* ---------- testimonial ----------------------------------------------------- */

/* Divi styles bare <blockquote> itself:
     blockquote { margin:20px 0 30px; border-left:5px solid; padding-left:20px }
     blockquote { border-color:#3550a0 }
   Reset all of it explicitly, with the ID-level guard, or the quote renders
   with Divi's blue bar and Divi's margins instead of ours. */
.aditi blockquote,
#et-boc .et-l .aditi blockquote {
  margin: 0;
  padding: 0;
  border: 0;
  width: 100%;
  max-width: none;
  quotes: none;
}

.aditi .quote,
#et-boc .et-l .aditi .quote {
  display: block;
  width: 100%;
  max-width: none;
  background: var(--bg-light);
  border: 0;
  border-left: 4px solid var(--cyan);
  border-radius: 0 6px 6px 0;
  padding: 32px 36px;
}
.aditi .quote q {
  display: block; font-size: 21px; line-height: 1.55;
  color: var(--navy); font-style: italic; quotes: none;
}
.aditi .quote q::before, .aditi .quote q::after { content: ''; }
.aditi .quote .who { font-style: normal; font-size: 14px; color: var(--mid); margin-top: 18px; }
.aditi .quote .who b { display: block; font-family: var(--head); font-size: 15px; font-weight: 600; color: var(--navy); }

/* ---------- testimonials ---------------------------------------------------- */
/* Spec: page-restructure-spec-v1.md section 3.
   "Section one carries visual weight. Larger type, more spacing, one per row.
    Sections two and three are more compact, several per row."
   No star ratings and no stock photography: initials only. */

.aditi .tlist { display: grid; gap: 20px; }
.aditi .tlist--lead { grid-template-columns: 1fr; }
.aditi .tlist--compact,
.aditi .tlist--crm { grid-template-columns: repeat(3, 1fr); gap: 18px; }

.aditi .tcard {
  display: flex;
  flex-direction: column;
  margin: 0;
  background: var(--bg-light);
  border: 1px solid var(--border);
  border-left: 4px solid var(--cyan);
  border-radius: 0 6px 6px 0;
  padding: 26px 30px;
}

.aditi .tcard q,
#et-boc .et-l .aditi .tcard q {
  display: block;
  font-size: 16px;
  line-height: 1.6;
  color: var(--navy);
  font-style: italic;
  quotes: none;
}
.aditi .tcard q::before, .aditi .tcard q::after { content: ''; }

/* Section one: one per row, larger type, more room. */
.aditi .tlist--lead .tcard { padding: 32px 36px; }
.aditi .tlist--lead .tcard q { font-size: 21px; line-height: 1.55; }

.aditi .tcard .who {
  display: flex; align-items: center; gap: 13px;
  margin: auto 0 0; padding-top: 20px;
}
/* Real photograph. Divi sets its own border-radius and max-width on images,
   so pin ours with the ID-level guard or the portraits render square. */
.aditi .tcard .avatar,
#et-boc .et-l .aditi .tcard .avatar {
  flex: 0 0 auto;
  width: 52px; height: 52px;
  border-radius: 50%;
  object-fit: cover;
  display: block;
  background: var(--bg-light);
  border: 1px solid var(--border);
  max-width: none;
}
/* Fallback where no photograph exists. */
.aditi .tcard .avatar--initials {
  background: var(--navy); color: var(--white); border-color: var(--navy);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--head); font-size: 15px; font-weight: 600;
  letter-spacing: .02em;
}
.aditi .tcard .who-text { min-width: 0; }

/* ---- option 3: portrait card, attribution above the quote ---------------- */

.aditi .tcard--portrait {
  background: var(--white);
  border: 1px solid var(--border);
  border-top: 3px solid var(--cyan);
  border-left: 1px solid var(--border);
  border-radius: 6px;
  padding: 24px 26px;
}
.aditi .tcard--portrait .t-head {
  display: flex; align-items: center; gap: 13px;
  margin: 0 0 18px;
  padding: 0 0 18px;
  border-bottom: 1px solid var(--border);
}
.aditi .tcard--portrait q,
#et-boc .et-l .aditi .tcard--portrait q {
  font-size: 15.5px;
  line-height: 1.65;
  color: var(--black);
  font-style: normal;
}

/* The name and role wrap to a different number of lines in each card, so the
   header heights differ and the dividing rules do not line up across the row.
   Subgrid makes the three cards share two rows: header, then quote.

   MUST stay after the `.aditi .tcard { display: flex }` rule above. @supports
   adds no specificity, so placed earlier the later `display: flex` would win
   and this would silently do nothing. */
@supports (grid-template-rows: subgrid) {
  .aditi .tlist--crm { grid-template-rows: auto 1fr; row-gap: 0; column-gap: 18px; }
  .aditi .tcard--portrait {
    display: grid;
    grid-row: span 2;
    grid-template-rows: subgrid;
    row-gap: 0;
  }
}
.aditi .tcard .who b,
#et-boc .et-l .aditi .tcard .who b {
  display: block;
  font-family: var(--head);
  font-size: 15px; font-weight: 600;
  color: var(--navy); line-height: 1.35;
}
.aditi .tcard .who span span,
.aditi .tcard .who-text > span { display: block; font-size: 13.5px; color: var(--mid); line-height: 1.4; }

/* ---------- legal pages ------------------------------------------------------ */
/* Long-form reading, so this is the one place a measure is set on body copy.
   04-typography.md asks for 60-80 characters a line; at 1200px full width a
   legal clause runs past 160 and becomes genuinely hard to follow. This caps
   LINE LENGTH, not the block: the Divi row still owns the width. */

.aditi .legal { max-width: 74ch; }

.aditi .legal p { font-size: 16px; line-height: 1.75; color: var(--black); margin: 0 0 18px; }

.aditi .legal h2,
#et-boc .et-l .aditi .legal h2 {
  font-size: 21px;
  line-height: 1.35;
  color: var(--navy);
  margin: 44px 0 14px;
  padding-top: 22px;
  border-top: 1px solid var(--border);
  /* An anchored clause must not land under a sticky header. */
  scroll-margin-top: 100px;
}
.aditi .legal > h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }

.aditi .legal-list { margin: 0 0 20px; padding: 0; list-style: none; }
.aditi .legal-list li {
  position: relative;
  font-size: 16px; line-height: 1.7; color: var(--black);
  padding-left: 20px; margin-bottom: 9px;
}
.aditi .legal-list li::before {
  content: '';
  position: absolute; left: 3px; top: 11px;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--cyan);
}

/* Table of contents */
.aditi .legal-toc {
  background: var(--bg-light);
  border: 1px solid var(--border);
  border-left: 3px solid var(--cyan);
  border-radius: 0 6px 6px 0;
  padding: 26px 30px;
  margin: 0 0 32px;
  scroll-margin-top: 100px;
}
.aditi .legal-toc-title {
  font-family: var(--head);
  font-size: 12px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--mid);
  margin: 0 0 6px;
}
.aditi .legal-toc-lead { font-size: 14.5px; color: var(--mid); margin: 0 0 14px; }
.aditi .legal-toc ol {
  margin: 0; padding: 0;
  list-style: none;
  counter-reset: toc;
  columns: 2; column-gap: 34px;
}
.aditi .legal-toc li { counter-increment: toc; margin: 0 0 8px; break-inside: avoid; }
.aditi .legal-toc a { font-size: 15px; line-height: 1.5; }
.aditi .legal-toc a::before {
  content: counter(toc) '. ';
  color: var(--mid);
  font-variant-numeric: tabular-nums;
}

.aditi .legal-back { margin: 0 0 6px; }
.aditi .legal-back a { font-family: var(--head); font-size: 13px; font-weight: 600; }
.aditi .legal-back a::before { content: '\2191  '; }

.aditi .legal-contact { font-size: 14.5px; color: var(--mid); margin-top: 22px; }

/* ---------- cta ------------------------------------------------------------- */

.aditi .cta-grid { display: grid; grid-template-columns: 1.15fr .85fr; gap: 44px; align-items: center; }
.aditi .cta-direct { margin-top: 26px; padding-top: 22px; border-top: 1px solid rgba(255,255,255,.18); font-size: 15px; }
.aditi .cta-direct li { margin-bottom: 8px; color: rgba(255,255,255,.82); }
.aditi .cta-direct a { color: var(--white); font-weight: 500; }
.aditi .cta-direct a:hover { color: var(--cyan); }

/* ==========================================================================
   CERTIFICATES
   Pairs with build-certificates.js. Two page types, one component set:
     /certificates/            the hub, one .ccard per person
     /<slug>-certificates/     one person, every .certitem they hold

   The brief was "graphic, and not written for a procurement officer". Within
   the constraints that already govern this file, that means the weight goes
   into GEOMETRY and SCALE, not into effects: a drawn stamp, an outlined index
   numeral, a moving ticker of credential codes, hard cyan rules. There is no
   gradient, no glow and no softening filter anywhere below, and there does
   not need to be. A stamp reads as a stamp because of the dashed ring, not
   because something behind it is glowing.
   -------------------------------------------------------------------------- */

/* ---------- the seal -------------------------------------------------------
   Drawn, not photographed. It does two jobs: hero decoration, and the stand-in
   for a certificate whose post has no scan attached. Same object both times,
   so the page never shows two different ideas of what a certificate looks like.
   Styled by element rather than by class, so the markup carries one class. */

.aditi .seal { display: block; width: 100%; height: auto; overflow: visible; }
.aditi .seal .seal-ring { fill: var(--white); stroke: var(--navy); stroke-width: 2; }
/* The perforated edge of a stamp, drawn as geometry. 3 on 5 is close enough
   to read as perforation at 90px and still resolve at 200px. */
.aditi .seal .seal-dash {
  fill: none; stroke: var(--cyan); stroke-width: 2; stroke-dasharray: 3 5; stroke-linecap: round;
}
.aditi .seal text { font-family: var(--head); text-anchor: middle; }
.aditi .seal .seal-lab { font-weight: 700; fill: var(--navy); letter-spacing: -.01em; }
/* 8.5px at .06em keeps a 16-character issuer inside the 92px dashed ring.
   Anything looser and "Microsoft Learn" runs out through the perforation. */
.aditi .seal .seal-sub {
  font-size: 8.5px; font-weight: 600; fill: var(--cyan-deep);
  letter-spacing: .06em; text-transform: uppercase;
}

/* ---------- hub hero -------------------------------------------------------
   Copy left, three overlapped seals right. They overlap on purpose: a row of
   three evenly spaced circles reads as a logo strip, a stack reads as a pile
   of things somebody actually earned. */

.aditi .cert-hero { display: grid; grid-template-columns: 1.15fr .85fr; gap: 48px; align-items: center; }
.aditi .cert-hero-copy .bar { margin-bottom: 26px; }
.aditi .cert-hero h1 { max-width: 15ch; }

.aditi .cert-seals { display: flex; align-items: center; justify-content: center; }
.aditi .cert-seals .seal { width: 148px; flex: 0 0 auto; }
/* Negative margin does the overlapping; rotation stops the stack reading as a
   printing error. Middle one forward and level, so the eye lands on it first. */
.aditi .cert-seals .seal:first-child { transform: rotate(-9deg); margin-right: -28px; }
.aditi .cert-seals .seal:nth-child(2) { width: 172px; position: relative; z-index: 2; }
.aditi .cert-seals .seal:last-child { transform: rotate(9deg); margin-left: -28px; }

/* ---------- ticker ---------------------------------------------------------
   Every credential code the team holds, moving. aria-hidden in the markup:
   it is the same list the page states properly further down, so a screen
   reader announcing it twice would be noise, not access.

   Two identical runs inside the track. Animating to -50% lands the second run
   exactly where the first began, so the loop has no seam and no gap. */

/* Sits directly under the hero, which is also a full-bleed panel, so .sec--panel
   leaves them touching. 14px of air stops the two rounded rectangles reading as
   one shape that failed to render. */
.aditi .ticker {
  margin-top: 14px;
  overflow: hidden;
  background: var(--navy);
  border-radius: 6px;
  padding: 15px 0;
  border-top: 3px solid var(--cyan);
}
.aditi .ticker-track { display: flex; width: max-content; animation: aditi-ticker 48s linear infinite; }
.aditi .ticker-run { display: flex; flex: 0 0 auto; }
.aditi .ticker-item {
  display: inline-flex; align-items: baseline; gap: 8px;
  padding: 0 26px;
  font-family: var(--head); font-size: 13px; font-weight: 500;
  letter-spacing: .03em; white-space: nowrap;
  color: rgba(255,255,255,.62);
  border-right: 1px solid rgba(255,255,255,.16);
}
/* Cyan on navy is 4.9:1, which passes AA. White on cyan, which does not, is
   the pairing that is banned. These are not the same thing. */
.aditi .ticker-item b {
  font-size: 15px; font-weight: 700; letter-spacing: .02em;
  text-transform: uppercase; color: var(--cyan);
}
@keyframes aditi-ticker { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* ---------- person cards on the hub ---------------------------------------- */

.aditi .cgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }

.aditi .ccard {
  position: relative;
  display: flex; flex-direction: column;
  background: var(--white);
  border: 1px solid var(--border);
  border-top: 3px solid var(--border);
  border-radius: 6px;
  padding: 26px 24px 22px;
  transition: border-color .18s ease, transform .18s ease;
}
/* Lift plus a cyan top rule. No shadow: the rule and the 3px reserved at rest
   mean nothing reflows on hover, and the card still moves. */
.aditi .ccard:hover { border-top-color: var(--cyan); transform: translateY(-3px); }
.aditi .ccard:focus-within { border-top-color: var(--cyan); }

/* Outlined numeral. Editorial, and it costs nothing: no image, no font file,
   and it degrades to a light grey number where text-stroke is unsupported. */
.aditi .ccard-idx {
  position: absolute; top: 16px; right: 20px;
  font-family: var(--head); font-size: 46px; font-weight: 700; line-height: 1;
  letter-spacing: -.03em;
  color: var(--border);
  -webkit-text-stroke: 1.5px var(--border);
  -webkit-text-fill-color: transparent;
}

/* Cut-out portrait on a navy disc with a cyan ring. The source images are
   background-removed PNGs, which is why a flat disc works and a photo crop
   would not. */
.aditi .ccard-face,
.aditi .phero-face,
.aditi .peer-face {
  display: block; overflow: hidden; flex: 0 0 auto;
  background: var(--navy);
  border-radius: 50%;
  border: 3px solid var(--cyan);
}
.aditi .ccard-face { width: 92px; height: 92px; margin-bottom: 18px; }
.aditi .ccard-face img,
.aditi .phero-face img,
.aditi .peer-face img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: top center;
}
/* Where there is no photograph the disc holds an initials avatar instead. It
   is square by construction and already navy, so it fills the circle exactly
   and needs no cropping. */
.aditi .ccard-face svg,
.aditi .phero-face svg,
.aditi .peer-face svg { display: block; width: 100%; height: 100%; }

.aditi .ccard-body { flex: 1 1 auto; }
.aditi .ccard h3 { margin-bottom: 4px; }
.aditi .ccard-role {
  font-family: var(--head); font-size: 13px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--cyan-deep);
  margin-bottom: 14px;
}
.aditi .ccard-count {
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  font-size: 14px; color: var(--mid);
  padding-bottom: 14px; margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.aditi .ccard-count b {
  font-family: var(--head); font-size: 26px; font-weight: 700; line-height: 1;
  color: var(--navy); font-variant-numeric: tabular-nums;
}
.aditi .ccard-since { font-size: 12.5px; margin-left: auto; }

.aditi .ccard-tags { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 20px; }
.aditi .ccard-tags li {
  font-family: var(--head); font-size: 11.5px; font-weight: 600;
  letter-spacing: .04em;
  padding: 5px 10px;
  color: var(--navy);
  background: var(--bg-light);
  border: 1px solid var(--border);
  border-radius: 3px;
}

.aditi .ccard-foot { display: flex; align-items: center; gap: 10px; }
.aditi .ccard-foot .btn { flex: 1 1 auto; }
/* Navy square, cyan on hover. Sized to match the button's height so the row
   has one baseline rather than two. */
.aditi .ccard-li {
  display: inline-flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; flex: 0 0 auto;
  color: var(--white); background: var(--navy);
  border-radius: 4px;
  transition: background .18s ease, color .18s ease;
}
.aditi .ccard-li:hover { background: var(--cyan); color: var(--navy); }

/* ---------- most recent rail ------------------------------------------------ */

.aditi .latest { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
/* The card chrome sits on the LIST ITEM, not on the anchor. A tile with no
   scan has nothing to open and so is not a link, and when the border lived on
   the anchor those tiles rendered as bare text in an otherwise bordered grid. */
.aditi .latest-item {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  transition: border-color .18s ease;
}
.aditi .latest-item:hover { border-color: var(--cyan); }
.aditi .latest-item a, .aditi .latest-still { display: block; height: 100%; }
.aditi .latest-thumb {
  display: flex; align-items: center; justify-content: center;
  height: 150px; padding: 14px;
  background: var(--bg-light);
  border-bottom: 1px solid var(--border);
}
.aditi .latest-thumb img { max-width: 100%; max-height: 100%; width: auto; height: auto; display: block; }
.aditi .latest-thumb .seal { width: 96px; }
.aditi .latest-meta { display: block; padding: 16px 18px 18px; }
.aditi .latest-meta b {
  display: block; font-family: var(--head); font-size: 15px; font-weight: 600;
  line-height: 1.35; color: var(--navy); margin-bottom: 6px;
}
.aditi .latest-meta > span { display: block; font-size: 13px; color: var(--mid); }
.aditi .latest-dot { color: var(--cyan-deep); }

/* ---------- person page hero ------------------------------------------------ */

.aditi .cert-back {
  display: inline-block;
  font-family: var(--head); font-size: 13px; font-weight: 600;
  letter-spacing: .04em; text-transform: uppercase;
  margin-bottom: 26px;
}
.aditi .cert-back::before { content: '\2190\00a0'; }

.aditi .phero-grid { display: grid; grid-template-columns: 168px 1fr; gap: 40px; align-items: start; }
.aditi .phero-face { width: 168px; height: 168px; }
.aditi .phero-body h1 { font-size: clamp(30px, 4vw, 46px); margin-bottom: 6px; }
.aditi .phero-role {
  font-family: var(--head); font-size: 15px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase;
  color: var(--cyan-deep);
  margin-bottom: 16px;
}
.aditi .phero .lead { max-width: 52ch; margin-bottom: 26px; }

.aditi .phero-meta {
  display: flex; flex-wrap: wrap; gap: 0;
  border: 1px solid var(--border); border-top: 3px solid var(--cyan);
  border-radius: 6px; overflow: hidden;
  background: var(--white);
  margin-bottom: 22px;
}
.aditi .phero-meta li { flex: 1 1 140px; padding: 18px 20px; }
.aditi .phero-meta li + li { border-left: 1px solid var(--border); }
.aditi .phero-meta b {
  display: block; font-family: var(--head); font-size: 28px; font-weight: 700;
  line-height: 1.05; color: var(--navy); font-variant-numeric: tabular-nums;
}
.aditi .phero-meta span { font-size: 13px; color: var(--mid); }

.aditi .phero-li {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--head); font-size: 14px; font-weight: 600;
}
.aditi .phero-nolink { font-size: 13.5px; color: var(--mid); }

/* ---------- certificate cards ----------------------------------------------- */

/* Year groups. The posts these came from are gone, so the date is the only
   ordering the reader has, and a sort order nobody can see is not an order.
   The year label makes it visible: newest year at the top, newest certificate
   first inside it. Vikas spans 2004 to 2025 and reads as a career this way. */
.aditi .certyears { display: grid; gap: 40px; }
.aditi .certyear { display: block; }
.aditi .certyear-label,
#et-boc .et-l .aditi .certyear-label {
  display: flex; align-items: center; gap: 16px;
  font-size: 22px; font-weight: 700; letter-spacing: -.01em;
  color: var(--navy);
  margin-bottom: 18px;
  font-variant-numeric: tabular-nums;
}
/* Rule that runs to the end of the row, so the year reads as a divider rather
   than as the heading of one more card. */
.aditi .certyear-label::after {
  content: ""; flex: 1 1 auto; height: 1px; background: var(--border);
}

.aditi .certlist { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }

.aditi .certitem {
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  transition: border-color .18s ease, transform .18s ease;
}
.aditi .certitem:hover { border-color: var(--cyan); transform: translateY(-3px); }
/* The scan and the title are two separate links to the same post, not one
   link wrapping the whole card. A "Verify" link has to sit inside the card,
   and an anchor inside an anchor is invalid, so the card is a container and
   the anchors are the parts a reader would actually click. The scan is taken
   out of the tab order and hidden from screen readers: it duplicates the
   title link beneath it, and announcing the same destination twice is noise. */
.aditi .certitem { display: flex; flex-direction: column; }
.aditi .certitem-shot { display: block; }

/* Certificate scans are portrait, landscape and screenshot, all in one grid.
   A fixed ratio with contain keeps the row even without cropping anyone's
   name off the top of their own certificate. */
.aditi .certitem-frame {
  display: flex; align-items: center; justify-content: center;
  position: relative;
  aspect-ratio: 4 / 3;
  padding: 16px;
  background: var(--bg-light);
  border-bottom: 1px solid var(--border);
}
.aditi .certitem-frame img { max-width: 100%; max-height: 100%; width: auto; height: auto; display: block; }
.aditi .certitem-frame--drawn { flex-direction: column; gap: 12px; }
.aditi .certitem-frame--drawn .seal { width: 116px; }
.aditi .certitem-noscan {
  font-family: var(--head); font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--mid);
}

.aditi .certitem-body { display: flex; flex-direction: column; flex: 1 1 auto; padding: 20px 22px 22px; position: relative; }
/* h4, not h3: the year above it is the h3. Sized like the old h3 because it
   is still the loudest thing in the card, and no longer padded on the right
   because the index numeral it was clearing has gone with the post links. */
.aditi .certitem h4, #et-boc .et-l .aditi .certitem h4 {
  font-size: 17px; line-height: 1.35; margin-bottom: 8px; color: var(--navy);
}

/* Code and kind sit on one line. The code is the credential you would search
   for; the kind is the qualifier that stops a membership card or a training
   module being read as a passed examination. Outline, not fill, so the two
   chips are visibly different weights of claim. */
.aditi .certitem-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 14px; }
.aditi .certitem-kind {
  display: inline-block;
  font-family: var(--head); font-size: 11.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  padding: 4px 9px;
  color: var(--mid); background: var(--white);
  border: 1px solid var(--border); border-radius: 3px;
}
.aditi .certitem-code {
  display: inline-block;
  font-family: var(--head); font-size: 11.5px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  padding: 5px 10px;
  color: var(--navy); background: var(--cyan);
  border-radius: 3px;
}
.aditi .certitem-meta {
  display: block;
  font-size: 13px; color: var(--mid);
  padding-top: 12px; margin-top: auto;
  border-top: 1px solid var(--border);
}
.aditi .certitem-issuer { display: flex; align-items: center; gap: 7px; color: var(--navy); font-weight: 500; }
.aditi .certitem-issuer svg { color: var(--cyan-deep); flex: 0 0 auto; }
.aditi .certitem-date { display: block; margin-top: 3px; }
.aditi .certitem-links { display: flex; flex-wrap: wrap; gap: 8px 18px; margin-top: 14px; }
.aditi .certitem .textlink { color: var(--cyan-deep); }
/* External, and it leaves the site, so it is labelled with the body it checks
   against rather than a bare "Verify" the reader has to hover to understand. */
.aditi .certitem-verify {
  font-family: var(--head); font-size: 13px; font-weight: 600;
  color: var(--mid);
  border-bottom: 1px solid var(--border);
}
.aditi .certitem-verify:hover { color: var(--navy); border-bottom-color: var(--cyan); }

/* ---------- other people ---------------------------------------------------- */

.aditi .peers { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 12px; }
.aditi .peer {
  display: flex; align-items: center; gap: 14px; height: 100%;
  padding: 14px 16px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 6px;
  transition: border-color .18s ease;
}
.aditi .peer:hover { border-color: var(--cyan); }
.aditi .peer-face { width: 48px; height: 48px; border-width: 2px; }
.aditi .peer-text { flex: 1 1 auto; min-width: 0; }
.aditi .peer-text b { display: block; font-family: var(--head); font-size: 15px; color: var(--navy); }
.aditi .peer-text span { display: block; font-size: 12.5px; color: var(--mid); }
.aditi .peer-n {
  flex: 0 0 auto;
  font-family: var(--head); font-size: 15px; font-weight: 700;
  color: var(--navy); background: var(--bg-light);
  border: 1px solid var(--border); border-radius: 4px;
  padding: 5px 11px;
  font-variant-numeric: tabular-nums;
}

/* ---------- closing panel --------------------------------------------------- */

.aditi .cert-cta h2 { max-width: 22ch; }
.aditi .cert-cta p { max-width: 56ch; }


/* ==========================================================================
   BLOG
   Pairs with divi/blog-template.php (the page that ships, which queries
   WordPress) and build-blog.js (the preview of the same markup).

   LAYOUT, set 21-Aug-2026: posts on the left, sidebar on the right, tags in a
   band across the bottom of both. The classic blog shape, which is what was
   asked for, and it earns its keep here: with only five posts listed, the
   sidebar is not decoration, it is the only route to the other eight.

   Not one published post has a featured image, so a post row is built out of
   type and chips. Add featured images later and the row takes one without any
   of this changing.
   -------------------------------------------------------------------------- */

.aditi .bloglayout {
  display: grid;
  grid-template-columns: 1fr 320px;
  gap: 30px;
  align-items: start;
}
/* Sticky on tall viewports only. Below that the sidebar is taller than the
   screen and sticking it would trap the bottom of it out of reach. */
@media (min-height: 900px) {
  .aditi .sidebar { position: sticky; top: 24px; }
}
.aditi .sidebar { display: grid; gap: 18px; }

/* ---------- sidebar widget --------------------------------------------------- */

.aditi .widget {
  background: var(--white);
  border: 1px solid var(--border);
  border-top: 3px solid var(--cyan);
  border-radius: 6px;
  padding: 22px 22px 20px;
}
.aditi .widget h3 {
  font-size: 14px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--navy);
  padding-bottom: 13px; margin-bottom: 15px;
  border-bottom: 1px solid var(--border);
}
/* The total lives in the heading, so the list below needs no summary row. */
.aditi .widget h3 b { color: var(--cyan-deep); font-variant-numeric: tabular-nums; }
/* ---------- archive: year tabs, one calendar ---------------------------------
   One calendar per year stacked works at two years and falls apart at twenty:
   the sidebar becomes a mile of mostly-empty grids. So the years are tabs and
   only the selected one draws.

   Tabs WRAP rather than scroll sideways. In a 320px sidebar a year chip is
   about 46px, so twenty years is four tidy rows and all of them are visible at
   once; a horizontal scroller would hide most of them behind a gesture nobody
   knows is there.

   Progressive enhancement: the server sends every panel visible. The script
   hides all but the first on load. With JavaScript off, the page falls back to
   exactly the stacked layout this replaced, which is worse but never broken.
   -------------------------------------------------------------------------- */

/* The wrapper the tab script hangs off. It carries no styling of its own; the
   rule exists so the class is declared rather than floating. */
.aditi .calarchive { display: block; }

.aditi .caltabs {
  display: flex; flex-wrap: wrap; gap: 5px;
  padding-bottom: 14px; margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
}
.aditi .caltab {
  font-family: var(--head); font-size: 12.5px; font-weight: 700;
  letter-spacing: .02em;
  padding: 6px 10px;
  color: var(--navy);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
  transition: border-color .18s ease, background .18s ease, color .18s ease;
}
.aditi .caltab:hover { border-color: var(--cyan); }
.aditi .caltab:focus-visible { outline: 2px solid var(--cyan); outline-offset: 2px; }
/* Selected. Navy fill with a white label: white on NAVY is fine, it is white
   on cyan that fails AA, which is why the cyan chips elsewhere carry navy text. */
.aditi .caltab[aria-selected='true'] {
  background: var(--navy); border-color: var(--navy); color: var(--white);
}

.aditi .calpanel-total {
  font-family: var(--head); font-size: 11px; font-weight: 600;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--mid);
  margin-bottom: 11px;
}
/* Stacked panels need separating when JavaScript is off and they all show. */
.aditi .calpanel + .calpanel { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--border); }

.aditi .calgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }

/* One month. Two lines: the abbreviation, and the count where there is one.
   Both states keep the same height so the grid stays square either way. */
.aditi .calmonth {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  min-height: 48px;
  padding: 6px 2px;
  border-radius: 4px;
  font-family: var(--head); font-size: 11px; font-weight: 700;
  letter-spacing: .05em; text-transform: uppercase;
  border: 1px solid var(--border);
  background: var(--bg-light);
  color: var(--mid);
}
.aditi .calmonth b {
  display: block; margin-top: 3px;
  font-size: 13px; font-weight: 700;
  font-variant-numeric: tabular-nums;
}
/* A month with posts. Navy on white with a cyan rule under it, so the active
   months read as a row of markers rather than as filled blocks. */
.aditi a.calmonth {
  background: var(--white);
  border-color: var(--border);
  border-bottom: 3px solid var(--cyan);
  color: var(--navy);
  transition: background .18s ease, border-color .18s ease;
}
.aditi a.calmonth b { color: var(--cyan-deep); }
.aditi a.calmonth:hover { background: var(--navy); border-color: var(--navy); color: var(--white); }
.aditi a.calmonth:hover b { color: var(--cyan); }
/* An empty month. Present, so the year keeps its shape, but plainly not a
   link: no border weight, no pointer, and the count line is left blank. */
.aditi .calmonth--off { opacity: .45; }



/* ---------- categories list ---------------------------------------------------- */

.aditi .widget-list { display: grid; gap: 1px; }
.aditi .widget-item {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  padding: 9px 0;
  font-size: 14.5px;
  color: var(--navy);
  border-bottom: 1px solid var(--border);
  transition: color .18s ease;
}
.aditi .widget-item:last-child { border-bottom: 0; }
.aditi .widget-item:hover { color: var(--cyan-deep); }
.aditi .widget-item span { flex: 1 1 auto; min-width: 0; }
.aditi .widget-item b {
  flex: 0 0 auto;
  font-family: var(--head); font-size: 12px; font-weight: 700;
  color: var(--mid);
  background: var(--bg-light);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 2px 8px;
  font-variant-numeric: tabular-nums;
}
.aditi .widget-item:hover b { color: var(--navy); border-color: var(--cyan); }

/* ---------- tag band --------------------------------------------------------
   Across the bottom of both columns. Tags are many, short and unordered by
   nature; a cloud is the shape that fits them, and full width is where a cloud
   stops wrapping into a ragged column. */

.aditi .cloud { display: flex; flex-wrap: wrap; gap: 8px; }
.aditi .cloud-tag {
  font-family: var(--head); font-size: 13px; font-weight: 500;
  color: var(--mid);
  padding: 7px 11px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 3px;
  transition: border-color .18s ease, color .18s ease;
}
.aditi .cloud-tag::before { content: '#'; color: var(--cyan-deep); }
.aditi .cloud-tag:hover { color: var(--navy); border-color: var(--cyan); }
.aditi .cloud-tag b { font-weight: 700; color: var(--navy); margin-left: 6px; font-variant-numeric: tabular-nums; }

/* Said once, under the lists, rather than repeated inside each of them. */
.aditi .browse-note { font-size: 13.5px; color: var(--mid); margin-top: 18px; }

/* ---------- meta chips ------------------------------------------------------
   Date and categories, one row, one family. The date is a chip because that
   was the brief: it should read like a category, not like a caption. */

.aditi .post-meta { display: flex; flex-wrap: wrap; gap: 7px; align-items: center; margin-bottom: 14px; }

.aditi .post-chip {
  display: inline-block;
  font-family: var(--head); font-size: 11.5px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  padding: 6px 11px;
  border-radius: 3px;
  white-space: nowrap;
}
/* Outline, navy label, tabular figures so a column of rows lines up. */
.aditi .post-chip--date {
  color: var(--navy);
  background: var(--white);
  border: 1px solid var(--border);
  font-variant-numeric: tabular-nums;
}
/* Filled cyan with a NAVY label; white on cyan is 2.7:1 and fails AA, which is
   why it appears nowhere in this file. */
.aditi .post-chip--cat { color: var(--navy); background: var(--cyan); }
/* Second and later categories step down to an outline, so a post filed under
   four of them does not read as four equally loud claims. */
.aditi .post-chip--alt { color: var(--mid); background: var(--white); border: 1px solid var(--border); }

/* ---------- post row -------------------------------------------------------- */

.aditi .postlist { display: grid; gap: 14px; }

.aditi .post {
  display: grid;
  grid-template-columns: 62px 1fr;
  align-items: start;
  background: var(--white);
  border: 1px solid var(--border);
  border-left: 3px solid var(--border);
  border-radius: 6px;
  padding: 24px 26px 22px;
  transition: border-color .18s ease, transform .18s ease;
}
/* The rule sits on the LEFT edge on a row, where it reads as a marker in a
   list. 3px is reserved at rest so nothing reflows when it turns cyan. */
.aditi .post:hover { border-left-color: var(--cyan); transform: translateX(3px); }
.aditi .post:focus-within { border-left-color: var(--cyan); }

/* Outlined numeral, the same device as the certificate person cards. No image,
   no font file, and it degrades to a light grey number where text-stroke is
   unsupported. */
.aditi .post-idx {
  font-family: var(--head); font-size: 30px; font-weight: 700; line-height: 1;
  letter-spacing: -.03em;
  color: var(--border);
  -webkit-text-stroke: 1.5px var(--border);
  -webkit-text-fill-color: transparent;
  font-variant-numeric: tabular-nums;
  padding-top: 2px;
}

.aditi .post-body { min-width: 0; }
/* The title carries the row: on a card with no photograph it is the only thing
   being read, and the two-column layout still leaves room for it. */
.aditi .post-body h3 { font-size: 21px; line-height: 1.3; margin-bottom: 10px; }
.aditi .post-body h3 a, #et-boc .et-l .aditi .post-body h3 a { color: var(--navy); }
.aditi .post-body h3 a:hover, #et-boc .et-l .aditi .post-body h3 a:hover { color: var(--cyan-deep); }
.aditi .post-excerpt { font-size: 15px; color: var(--mid); margin-bottom: 0; }

.aditi .post-foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;
  padding-top: 15px; margin-top: 15px;
  border-top: 1px solid var(--border);
}
.aditi .post-tags { display: flex; flex-wrap: wrap; gap: 10px; }
/* Tags are the quiet layer: the hash marks them without a label, and they stay
   grey so they never compete with the chips above. */
.aditi .post-tag {
  font-family: var(--head); font-size: 12px; font-weight: 500;
  color: var(--mid);
  transition: color .18s ease;
}
.aditi .post-tag::before { content: '#'; color: var(--cyan-deep); }
.aditi .post-tag:hover { color: var(--navy); }
.aditi .post-foot .textlink { margin-left: auto; color: var(--cyan-deep); }

/* ---------- pagination -------------------------------------------------------
   Archives paginate; the blog page does not. That difference is deliberate:
   the blog page is a shop window, five posts and no back button, while an
   archive is the destination somebody clicked to reach and has to be able to
   show everything in it.
   -------------------------------------------------------------------------- */

.aditi .pager {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-top: 20px;
}
.aditi .pager a, .aditi .pager span {
  display: inline-block; min-width: 42px; text-align: center;
  font-family: var(--head); font-size: 14px; font-weight: 600;
  padding: 10px 14px;
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--navy);
  background: var(--white);
  font-variant-numeric: tabular-nums;
  transition: border-color .18s ease, background .18s ease, color .18s ease;
}
.aditi .pager a:hover { border-color: var(--cyan); color: var(--navy); }
.aditi .pager .pager-on { background: var(--navy); border-color: var(--navy); color: var(--white); }
/* The ellipsis between page ranges is a label, not a control. */
.aditi .pager .pager-gap { border: 0; background: none; color: var(--mid); min-width: 0; padding: 10px 4px; }

/* ---------- empty state ----------------------------------------------------- */

.aditi .blog-none {
  padding: 40px 30px;
  background: var(--bg-light);
  border: 1px solid var(--border);
  border-top: 3px solid var(--cyan);
  border-radius: 6px;
  text-align: center;
  color: var(--mid);
}


/* ==========================================================================
   CONTACT FORM
   Pairs with divi-child/contact-template.php and divi-child/aditi-contact.php.

   A form is the one place on a site where the design has a job beyond looking
   right: every ambiguity costs a submission. So the rules here are about
   legibility under pressure, not decoration. Labels above fields, never
   placeholders as labels. Required marked on the label, not by colour alone.
   Errors named next to the field that caused them. Touch targets at 48px.
   -------------------------------------------------------------------------- */

.aditi .form { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.aditi .field { display: flex; flex-direction: column; min-width: 0; }
/* Message and consent run the full width; a 400px-wide textarea invites a
   one-line answer, which is the opposite of what this page is for. */
.aditi .field--wide { grid-column: 1 / -1; }

.aditi .field label {
  font-family: var(--head); font-size: 13.5px; font-weight: 600;
  letter-spacing: .02em;
  color: var(--navy);
  margin-bottom: 7px;
}
/* "Required" in words, not an asterisk and not colour. An asterisk means
   nothing to a first-time visitor and colour alone fails WCAG 1.4.1. */
.aditi .field label span {
  font-weight: 500; color: var(--mid); text-transform: none; letter-spacing: 0;
}

.aditi .field input,
.aditi .field textarea,
.aditi .field select,
#et-boc .et-l .aditi .field input,
#et-boc .et-l .aditi .field textarea,
#et-boc .et-l .aditi .field select {
  font-family: var(--body); font-size: 16px; line-height: 1.5;
  color: var(--black);
  /* 16px is not a style choice. Below 16px, iOS Safari zooms the whole page
     when the field is focused and the visitor loses their place. */
  width: 100%;
  padding: 13px 15px;
  min-height: 48px;
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 4px;
  transition: border-color .18s ease;
  -webkit-appearance: none;
  appearance: none;
}
.aditi .field textarea { min-height: 150px; resize: vertical; }

.aditi .field input:hover,
.aditi .field textarea:hover,
.aditi .field select:hover { border-color: var(--mid); }

.aditi .field input:focus,
.aditi .field textarea:focus,
.aditi .field select:focus {
  outline: 2px solid var(--cyan);
  outline-offset: 1px;
  border-color: var(--cyan-deep);
}

/* The native arrow is removed by appearance:none above, so one is drawn back
   with a border triangle. No background-image: this file ships no assets. */
.aditi .select-wrap { position: relative; }
.aditi .select-wrap::after {
  content: '';
  position: absolute; right: 16px; top: 50%; margin-top: -3px;
  width: 0; height: 0; pointer-events: none;
  border-left: 5px solid transparent;
  border-right: 5px solid transparent;
  border-top: 6px solid var(--navy);
}
.aditi .select-wrap select { padding-right: 38px; }

.aditi .field-note { font-size: 13px; color: var(--mid); margin-top: 7px; }

/* A field that failed validation. The red is carried by the WORD "required"
   in the note, not by the border alone, so it survives a colour-blind reader
   and a monochrome print. The palette has no red, so the marker is the cyan
   rule plus the text. */
.aditi .field--bad input,
.aditi .field--bad textarea,
.aditi .field--bad select { border-color: var(--navy); border-left-width: 3px; }
.aditi .field--bad .field-note { color: var(--navy); font-weight: 600; }

/* Honeypot. Not display:none: some bots skip hidden fields, and screen readers
   need the label for the instruction. Off-screen and out of the tab order. */
.aditi .hp {
  position: absolute !important;
  left: -9999px; width: 1px; height: 1px; overflow: hidden;
}

.aditi .form-actions {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px 20px;
  padding-top: 4px;
}
.aditi .form-actions .btn { min-height: 48px; }
.aditi .form-actions p { font-size: 13.5px; color: var(--mid); margin: 0; }

/* ---------- result banners --------------------------------------------------
   Shown after the redirect, above the form. A banner and nothing else would
   leave a visitor wondering whether to send it again, so the success state
   also says what happens next and by when. */

.aditi .form-msg {
  padding: 22px 24px;
  border: 1px solid var(--border);
  border-radius: 6px;
  margin-bottom: 28px;
}
.aditi .form-msg h2 { font-size: 20px; margin-bottom: 8px; }
.aditi .form-msg p { font-size: 15px; color: var(--mid); margin-bottom: 0; }
.aditi .form-msg--ok { background: var(--bg-light); border-top: 3px solid var(--cyan); }
.aditi .form-msg--bad { background: var(--white); border-top: 3px solid var(--navy); }

/* ---------- the panel beside the form --------------------------------------- */

.aditi .contact-grid { display: grid; grid-template-columns: 1.35fr .65fr; gap: 44px; align-items: start; }
.aditi .contact-aside { display: grid; gap: 18px; }


/* ---------- responsive ------------------------------------------------------ */

@media (max-width: 980px) {
  /* contact, 980. The aside drops under the form rather than squeezing to a
     column too narrow to read. */
  .aditi .contact-grid { grid-template-columns: 1fr; gap: 26px; }
  /* certificates, 980. RESTORED 21-Aug-2026: these were deleted by accident
     when the blog CSS was swapped in, and the certificates pages went
     unresponsive without anyone noticing, because only the blog was re-tested
     at phone width. Every page is checked now, see tools/check-responsive.js. */
  .aditi .cert-hero { grid-template-columns: 1fr; gap: 34px; }
  .aditi .cert-hero h1 { max-width: 20ch; }
  .aditi .cert-seals { justify-content: flex-start; }
  .aditi .cert-seals .seal { width: 118px; }
  .aditi .cert-seals .seal:nth-child(2) { width: 136px; }
  .aditi .cgrid, .aditi .certlist, .aditi .latest { grid-template-columns: repeat(2, 1fr); }
  .aditi .phero-grid { grid-template-columns: 128px 1fr; gap: 28px; }
  .aditi .phero-face { width: 128px; height: 128px; }
  /* blog, 980. The sidebar goes under the posts. It is navigation, not
     decoration, so it stays on the page rather than being hidden. */
  .aditi .bloglayout { grid-template-columns: 1fr; gap: 22px; }
  .aditi .sidebar { position: static; grid-template-columns: 1fr 1fr; }
  .aditi .post { padding: 22px 22px 20px; }
  .aditi .post-body h3 { font-size: 19px; }
  .aditi .trust-grid { grid-template-columns: 1fr; gap: 16px; }
  .aditi .stats { grid-template-columns: repeat(2, 1fr); }
  .aditi .hero-split { grid-template-columns: 1fr; gap: 28px; }
  .aditi .hero-media { order: -1; padding: 14px 16px 0; }
  .aditi .hero-media img { max-width: 280px; }
  .aditi .tlist--compact, .aditi .tlist--crm { grid-template-columns: repeat(2, 1fr); }
  .aditi h1 { font-size: 34px; }
  .aditi h2 { font-size: 25px; }
  .aditi .sec { padding: 52px 0; }
  .aditi .navy, .aditi .panel-light { padding: 42px 30px; }
  /* One column: there is nothing left to align across, so drop back to flex.
     Leaving subgrid on would make every card share one 5-row track list. */
  .aditi .lanes { grid-template-columns: 1fr; grid-template-rows: none; }
  .aditi .lane { display: flex; grid-row: auto; }
  .aditi .lane .lane-foot { margin-top: auto; }
  .aditi .phases { grid-template-columns: 1fr; gap: 22px; }
  .aditi .cta-grid { grid-template-columns: 1fr; gap: 30px; }
}

@media (max-width: 700px) {
  /* contact, 700. One field per row. Two 160px inputs side by side is how you
     get a phone number typed into the email box. */
  .aditi .form { grid-template-columns: 1fr; gap: 16px; }
  .aditi .form-actions .btn { width: 100%; }
  /* certificates, 700. Restored with the block above. One column throughout: a
     two-up certificate scan on a phone is 150px wide and unreadable, which
     defeats the entire point of showing the scan. */
  .aditi .cgrid, .aditi .certlist, .aditi .latest { grid-template-columns: 1fr; }
  .aditi .cert-hero { gap: 28px; }
  .aditi .cert-seals .seal { width: 96px; }
  .aditi .cert-seals .seal:nth-child(2) { width: 112px; }
  .aditi .ccard { padding: 22px 20px 20px; }
  .aditi .ccard-idx { font-size: 34px; }
  .aditi .ccard-foot .btn { display: inline-block; }
  .aditi .phero-grid { grid-template-columns: 1fr; gap: 22px; }
  .aditi .phero-face { width: 112px; height: 112px; }
  .aditi .phero-meta li { flex: 1 1 100%; }
  .aditi .phero-meta li + li { border-left: 0; border-top: 1px solid var(--border); }
  .aditi .certitem-frame { aspect-ratio: 3 / 2; }
  .aditi .certyears { gap: 30px; }
  /* blog, 700. The index numeral moves above the title: a 62px gutter on a
     360px screen leaves the title 260px and it wraps to five lines. */
  .aditi .sidebar { grid-template-columns: 1fr; }
  .aditi .post { grid-template-columns: 1fr; gap: 8px; padding: 20px 20px 18px; }
  .aditi .post-idx { font-size: 24px; padding-top: 0; }
  .aditi .post-body h3 { font-size: 18px; }
  .aditi .post-foot .textlink { margin-left: 0; }
  .aditi .widget { padding: 20px 20px 18px; }
  .aditi .calgrid { grid-template-columns: repeat(6, 1fr); }
  .aditi .caltabs { padding-bottom: 12px; margin-bottom: 12px; }
  .aditi .legal-toc ol { columns: 1; }
  .aditi .legal-toc { padding: 20px 20px; }
  .aditi .taglist li { font-size: 13px; padding: 6px 12px; }
  .aditi .tagblocks { gap: 24px; }
  .aditi .stats { grid-template-columns: 1fr; }
  .aditi .stats li { padding: 22px 20px; }
  .aditi .stats b { font-size: 30px; }
  .aditi h1 { font-size: 28px; }
  .aditi h2 { font-size: 22px; }
  .aditi h3 { font-size: 18px; }
  .aditi .sec { padding: 44px 0; }
  .aditi .head { margin-bottom: 28px; }
  .aditi .navy, .aditi .panel-light { padding: 30px 22px; border-radius: 4px; }
  .aditi .hero .lead { font-size: 17px; }
  .aditi .fears { grid-template-columns: 1fr; gap: 16px; }
  .aditi .proof { grid-template-columns: 1fr; }
  .aditi .guarantee { padding: 24px 22px; }
  .aditi .guarantee q { font-size: 17px; }
  .aditi .sec-more { padding: 22px 20px; }
  .aditi .sec-more .btn { width: 100%; }
  .aditi .cs-list { grid-template-columns: 1fr; gap: 14px; }
  .aditi .cs-item { padding: 22px 20px; }
  .aditi .cs-item .btn { width: 100%; }
  .aditi .tlist--compact, .aditi .tlist--crm { grid-template-columns: 1fr; grid-template-rows: none; }
  .aditi .tcard--portrait { display: flex; grid-row: auto; }
  .aditi .tcard, .aditi .tlist--lead .tcard { padding: 22px 20px; }
  .aditi .tlist--lead .tcard q { font-size: 18px; }
  .aditi .pgrid { grid-template-columns: 1fr; gap: 14px; }
  .aditi .pcard { padding: 20px 18px; }
  .aditi .pmore .btn { width: 100%; }
  .aditi .quote { padding: 22px 20px; }
  .aditi .quote q { font-size: 18px; }
  .aditi .btn { display: block; text-align: center; }
  .aditi .btns { display: block; }
  .aditi .btns .btn + .btn { margin-top: 10px; }
}

@media (prefers-reduced-motion: reduce) {
  .aditi .post:hover { transform: none; }
  /* A marquee is motion the reader did not ask for. Stopped, the ticker still
     reads as a strip of credential codes, so nothing is lost by holding it. */
  .aditi .ticker-track { animation: none; }
  .aditi .ccard:hover, .aditi .certitem:hover { transform: none; }
  .aditi *, .aditi *::before, .aditi *::after { transition-duration: .01ms !important; }
  .aditi .lane:hover { transform: none; }
}
