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

/* ===== GENERATED by build-native.js. Do not edit. =====
   Sources, in order: assets/css/aditi-brand.css,
   assets/css/aditi-visuals.css, aditi-services-overrides.css,
   aditi-services-map.css.
   Edit those, then re-run: node build-native.js
   ===================================================== */


/* ==========================================================================
   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; }
}

/* Four cards from 27-Aug-2026, when Offer B was added in position 2. Two by
   two rather than four across: four across leaves each card 282px inside the
   1200px Divi row, too narrow for the 19px headings, and the pairing puts the
   two AI offers on one row, which is where a visitor compares them.
   Below 981px the responsive block further down already drops to one column. */
@media (min-width: 981px) {
  .aditi .lanes--home { grid-template-columns: repeat(2, 1fr); }

  @supports (grid-template-rows: subgrid) {
    /* Two rows of cards now, so the four-row track list repeats twice. */
    .aditi .lanes--home { grid-template-rows: repeat(2, auto auto 1fr auto); }
    /* row-gap stays 0 above, or the subgrid spaces each card's own internals
       by the same amount. The gap between the two rows of cards rides on the
       second row's top margin instead. */
    .aditi .lanes--home > .lane:nth-child(n+3) { margin-top: 34px; }
  }
}


/* ---------- 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; }
/* A second line in a trust card, added 27-Aug-2026 for the Offer B sibling on
   /about/. The margin above is 0 so the cards close up tight against the box;
   without this the two lines run together as one paragraph. */
.aditi .trust p + p { margin-top: 10px; }

/* ---------- 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; }
}


/* ==========================================================================
   Aditi IT Software Solutions — diagram layer for the Services page
   Companion to aditi-brand.css. ADDITIVE ONLY.

   Load AFTER aditi-brand.css. Nothing in here overrides a rule in that file;
   every selector is a class that file does not define. Removing this file
   leaves the page intact, minus the diagrams.

   Pairs with:  divi/code/software-services-visual.html
   --------------------------------------------------------------------------
   Constraints this file is written under (brandcheck.js enforces all of them):
     - No raw hex. Colour comes from the vars declared on .aditi in
       aditi-brand.css, so the palette cannot drift out of the approved nine.
     - No gradient fills, no glass effect, no softening filter, no shadow or
       glow of any kind. brandcheck greps the raw stylesheet for each of those
       property names, comments included, so do not name them even in prose.
     - Zero dot-grid gradients. That one-use budget belongs to .dots in
       aditi-brand.css. Diagram texture, where needed, is SVG geometry.
     - Every class used in the HTML has a rule here or in aditi-brand.css.
   --------------------------------------------------------------------------
   The idea every diagram carries: ONE BOUNDARY, and nothing outside it that
   the client has to manage. Six visuals, one argument. That is why they use a
   shared primitive set rather than being drawn one at a time.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. Shared diagram primitives

   Diagrams are inline SVG with a viewBox and no width attribute, so they
   scale with their column and never need a second asset for mobile. Colour
   and type live here rather than on the SVG elements, which keeps hex out of
   the markup and means a palette change is one edit, not eighty.
   -------------------------------------------------------------------------- */

.aditi .dgm {
  display: block;
  width: 100%;
  height: auto;
}

/* Montserrat, matching every other label on the page. Without this the SVG
   falls back to the browser's default serif and reads as a foreign object. */
.aditi .dgm text { font-family: var(--head); }

/* Type roles inside a diagram. Four, deliberately: a section kicker, a thing
   that is named, a thing that is explained, and the one point that matters. */
.aditi .t-kick {
  font-size: 11.5px; font-weight: 600;
  letter-spacing: .09em; text-transform: uppercase;
  fill: var(--cyan-deep);
}
.aditi .t-lab { font-size: 14px; font-weight: 600; fill: var(--navy); }
.aditi .t-mut { font-size: 12px; font-weight: 500; fill: var(--mid); }
.aditi .t-key { font-size: 13px; font-weight: 600; fill: var(--cyan-deep); }

/* Stroke and fill roles. 1.7px matches the line-icon weight already on the
   page (guidelines/06-visual-style.md: 1.5-2px at 24px), so the diagrams and
   the icons read as one drawing hand. */
.aditi .s-navy { fill: none; stroke: var(--navy); stroke-width: 1.7; }
.aditi .s-cyan { fill: none; stroke: var(--cyan); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
/* Dashed = the thing that is separate from you. Used once, on the vendor box
   in the hero, and nowhere else, so the dash carries meaning rather than
   decoration. */
.aditi .s-dash { fill: none; stroke: var(--border); stroke-width: 1.7; stroke-dasharray: 5 5; }

.aditi .f-navy  { fill: var(--navy); }
.aditi .f-cyan  { fill: var(--cyan); }
.aditi .f-light { fill: var(--bg-light); }
.aditi .f-line  { fill: var(--border); }

/* One line of plain English under a diagram. The diagram carries the shape,
   this carries the claim, and a reader who only reads captions still gets the
   argument. */
.aditi .dgm-cap {
  margin: 16px 0 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--mid);
}


/* --------------------------------------------------------------------------
   2. Hero — "inside vs outside"

   Frame is its own class, not .hero-media. That one is built for a cut-out
   portrait: flex-end alignment and zero bottom padding so the figure stands on
   the base. An SVG needs even padding on all four sides instead.
   -------------------------------------------------------------------------- */

.aditi .hero-figure {
  background: var(--white);
  border: 1px solid var(--border);
  border-bottom: 3px solid var(--cyan);
  border-radius: 8px;
  padding: 26px 26px 22px;
}


/* --------------------------------------------------------------------------
   3. The acceptance gate

   The most important diagram on the page. The guarantee copy is locked
   verbatim and cannot be shortened, so this is the only way a scanner gets it.

   Two SVGs, not one. A 900-unit viewBox squeezed into a 360px phone would
   render 14px labels at about 5px. Horizontal below 700px is not a layout
   problem, it is an unreadable one, so the rail rotates to a vertical version
   with its own viewBox and full-size type.
   -------------------------------------------------------------------------- */

.aditi .gate {
  margin-bottom: 36px;
  padding: 28px 30px 24px;
  background: var(--bg-light);
  border-radius: 6px;
}
.aditi .gate-tall { display: none; }

/* The cyan bar draws itself once, on load. transform-box: fill-box makes the
   percentage origin resolve against the rect's own box rather than the SVG
   viewport, which is what keeps it growing from its own centre. */
.aditi .gate-mark {
  transform-box: fill-box;
  transform-origin: 50% 50%;
  animation: aditi-gate .45s ease-out .3s both;
}
@keyframes aditi-gate {
  from { transform: scaleY(0); }
  to   { transform: scaleY(1); }
}


/* --------------------------------------------------------------------------
   4. Service lane diagrams

   Replaces the 48px .lane-icon. .lanes uses subgrid, and the icon sits in row
   one, so all three diagrams align to the tallest automatically. Nothing about
   the grid needs changing.
   -------------------------------------------------------------------------- */

.aditi .lane-dgm {
  margin-bottom: 20px;
  padding: 16px 18px 14px;
  background: var(--bg-light);
  border-radius: 6px;
}

/* Four lanes since 27-Aug-2026, when Offer B was added in position 2. Opt-in
   by class rather than by count, so the three-lane .lanes blocks on every other
   page are untouched.

   Two by two, not four across: at four across each lane is 282px inside the
   1200px row, which renders a 260-unit diagram at 0.7 scale and its 12px
   labels at about 9px. The diagrams are the argument on this page, so the
   column stays wide and the lanes wrap instead.

   Below 981px the breakpoint block further down already drops to one column. */
@media (min-width: 981px) {
  .aditi .lanes--four { grid-template-columns: repeat(2, 1fr); }

  @supports (grid-template-rows: subgrid) {
    /* Two rows of lanes now, so the five-row track list repeats twice. */
    .aditi .lanes--four { grid-template-rows: repeat(2, auto auto auto 1fr auto); }
    /* row-gap stays 0, or the subgrid spaces each lane's own internals by the
       same amount. The gap between the two rows rides on the margin instead. */
    .aditi .lanes--four > .lane:nth-child(n+3) { margin-top: 34px; }
  }
}


/* --------------------------------------------------------------------------
   5. Proof — the replacement chip

   Not a before/after bar chart. A bar implies a magnitude, and three of these
   five projects have no client-confirmed magnitude to plot (README.md flags 12
   such metrics across the site). What the copy DOES state, in the client's own
   published words, is what each system replaced. So the visual asserts exactly
   that and nothing more: struck-through old state, arrow, new state.
   -------------------------------------------------------------------------- */

.aditi .swap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin: 16px 0 0;
  font-family: var(--head);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.4;
}
.aditi .swap-was {
  color: var(--mid);
  text-decoration: line-through;
  text-decoration-color: var(--border);
  text-decoration-thickness: 2px;
}
/* Drawn rather than typed. A glyph arrow inherits the body font's metrics and
   sits off the optical centre next to 12.5px caps. */
.aditi .swap-arrow {
  position: relative;
  flex: 0 0 auto;
  width: 18px;
  height: 1.7px;
  background: var(--navy);
}
.aditi .swap-arrow::after {
  content: '';
  position: absolute;
  right: 0;
  top: -3.2px;
  width: 8px;
  height: 8px;
  border-top: 1.7px solid var(--navy);
  border-right: 1.7px solid var(--navy);
  transform: rotate(45deg);
}
.aditi .swap-now {
  color: var(--navy);
  border-bottom: 2px solid var(--cyan);
}

/* The stat band above the case studies. Reuses .stats wholesale; this only
   sets the gap beneath it. */
.aditi .stats--proof { margin-bottom: 34px; }


/* --------------------------------------------------------------------------
   6. Objection chips

   The densest text block on the page. The chip is the resolved state: a
   scanner gets all four answers without reading four paragraphs, and the
   paragraphs stay for anyone who wants the detail.
   -------------------------------------------------------------------------- */

.aditi .fear-chip {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0 0 10px;
  padding: 5px 13px 5px 10px;
  font-family: var(--head);
  font-size: 12px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--navy);
  background: var(--white);
  border: 1px solid var(--border);
  border-radius: 999px;
}
/* aditi-brand.css nudges .fear svg down 2px to sit level with an h4. Inside a
   chip there is no h4 to align to, so that nudge has to come back off. */
.aditi .fear-chip svg {
  margin-top: 0;
  color: var(--cyan-deep);
  flex: 0 0 auto;
}


/* --------------------------------------------------------------------------
   7. Breakpoints. Mirrors the 980 / 700 pair in aditi-brand.css.
   -------------------------------------------------------------------------- */

@media (max-width: 980px) {
  /* Same call aditi-brand.css makes for .hero-media: the visual leads on a
     phone, the headline follows. */
  .aditi .hero-figure { order: -1; padding: 20px 20px 18px; }
  .aditi .gate { padding: 24px 22px 20px; }
}

@media (max-width: 700px) {
  .aditi .hero-figure { padding: 16px 16px 14px; }
  .aditi .gate { padding: 20px 18px 16px; margin-bottom: 28px; }
  .aditi .gate-wide { display: none; }
  .aditi .gate-tall { display: block; }
  .aditi .lane-dgm { padding: 14px 16px 12px; }
  .aditi .stats--proof { margin-bottom: 26px; }
  .aditi .swap { gap: 8px; font-size: 12px; }
  .aditi .dgm-cap { font-size: 12.5px; }
}

@media (prefers-reduced-motion: reduce) {
  .aditi .gate-mark { animation: none; }
}


/* ==========================================================================
   ROUND 2 — added 19-Aug-2026 after review.

   Brief: more to look at, less to read. Every section on the page now carries
   something visual, and the five blocks below are the ones that were still
   text-only.

   Same rule as round one: they all restate ONE BOUNDARY, and nothing outside
   it that the client has to manage.
   ========================================================================== */


/* --------------------------------------------------------------------------
   8. "Who we work with" — the fit picture

   Was a five-sentence paragraph describing the reader's situation. A reader
   who does not read paragraphs got nothing from that section at all.

   Two columns, and the styling carries the whole argument before a word is
   read: solid navy chips under a cyan cap are covered, dashed grey chips under
   a grey cap are not. Built in HTML rather than SVG on purpose. An SVG of this
   would need a second hand-drawn version for phones; chips reflow by
   themselves.
   -------------------------------------------------------------------------- */

.aditi .fit {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin-bottom: 30px;
}
.aditi .fit-col { padding-top: 18px; }
/* Covered. Same 3px cyan rule the last .phase carries, so "this is handled"
   reads the same way in both places. */
.aditi .fit-col--in  { border-top: 3px solid var(--cyan); }
/* Not covered. Dashed, and the dash is the only place on this page it means
   anything other than "separate from you". */
.aditi .fit-col--out { border-top: 3px dashed var(--border); }

.aditi .fit-cap {
  margin: 0 0 14px;
  font-family: var(--head);
  font-size: 12px; font-weight: 600;
  letter-spacing: .05em; text-transform: uppercase;
}
.aditi .fit-cap--in  { color: var(--cyan-deep); }
.aditi .fit-cap--out { color: var(--mid); }

.aditi .fit-set { display: flex; flex-direction: column; gap: 10px; }
.aditi .fit-chip {
  padding: 13px 16px;
  font-family: var(--head);
  font-size: 14px; font-weight: 600; line-height: 1.4;
  color: var(--navy);
  background: var(--white);
  border: 1.7px solid var(--navy);
  border-radius: 6px;
}
.aditi .fit-chip--out {
  color: var(--mid);
  background: var(--bg-light);
  border: 1.7px dashed var(--border);
}


/* --------------------------------------------------------------------------
   9. The guarantee seal

   The strongest commitment on the page sat in a plain quote block with nothing
   to catch the eye. A seal is the right form: it is what a guarantee looks
   like everywhere else in the world, so it needs no explaining.

   The dashed inner ring is the perforation of a stamp. It is the one
   decorative flourish in the whole set, and it is spent here because this is
   the sentence that carries a financial penalty.
   -------------------------------------------------------------------------- */

.aditi .gtee-grid {
  display: grid;
  grid-template-columns: 88px 1fr;
  gap: 26px;
  align-items: start;
}
.aditi .gtee-seal { display: block; width: 88px; }
.aditi .s-seal {
  fill: none;
  stroke: var(--cyan);
  stroke-width: 1.7;
  stroke-dasharray: 2.6 3.4;
}


/* --------------------------------------------------------------------------
   10. Case study glyphs

   Five cards that opened with three near-identical lines of grey text. The
   glyph tells you what kind of system it is before you read whose it is, which
   is the fastest thing a scanner can be given.
   -------------------------------------------------------------------------- */

.aditi .proof-head {
  display: grid;
  grid-template-columns: 44px 1fr;
  gap: 14px;
  align-items: start;
  margin-bottom: 12px;
}
.aditi .proof-ico {
  display: flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  color: var(--navy);
  background: var(--bg-light);
  border-radius: 6px;
}
/* .what carries the bottom gap when it is the last line of the header block.
   Inside .proof-head the grid owns that spacing instead. */
.aditi .proof-head .what { margin-bottom: 0; }


/* --------------------------------------------------------------------------
   11. Testimonial avatar

   Initials on navy, matching lib/avatar.js exactly (its NAVY on its WHITE, at
   its proportions) so this face and the ones generated on the Client Speak
   page are the same object. A real photograph would be better and should
   replace it the moment we have one cleared.
   -------------------------------------------------------------------------- */

.aditi .q-foot { display: flex; align-items: center; gap: 16px; }
.aditi .q-avatar { display: block; flex: 0 0 auto; width: 56px; }
/* 19.6px and the y=35 baseline in the markup are lib/avatar.js's own formula
   solved for r=28: fontSize = 42 * (r/60), baseline = r + 15 * (r/60). Matching
   it exactly is what makes this face and a generated one the same object. */
.aditi .t-ini {
  font-size: 19.6px; font-weight: 700;
  fill: var(--white);
}


/* --------------------------------------------------------------------------
   12. "What you leave knowing"

   The CTA promised three specific answers inside one long sentence. Three
   tiles say the same thing in a glance, and a reader deciding whether to book
   a call is exactly the reader least willing to parse a long sentence.

   Cyan icons on navy: icons and short labels only, never body text, which is
   the one use 03-colors.md permits on this pairing.
   -------------------------------------------------------------------------- */

.aditi .know {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  margin-top: 26px;
  background: rgba(255,255,255,.18);
  border: 1px solid rgba(255,255,255,.18);
  border-radius: 6px;
  overflow: hidden;
}
.aditi .know-item {
  display: flex; flex-direction: column; gap: 9px;
  padding: 18px 20px;
  background: var(--navy);
}
.aditi .know-item svg { color: var(--cyan); flex: 0 0 auto; }
.aditi .know-lab {
  font-family: var(--head);
  font-size: 14px; font-weight: 600; line-height: 1.4;
  color: var(--white);
}


/* --------------------------------------------------------------------------
   13. Round-2 breakpoints
   -------------------------------------------------------------------------- */

@media (max-width: 980px) {
  .aditi .know { grid-template-columns: 1fr; }
}

@media (max-width: 700px) {
  .aditi .fit { grid-template-columns: 1fr; gap: 20px; margin-bottom: 24px; }
  .aditi .fit-chip { padding: 11px 14px; font-size: 13.5px; }
  .aditi .gtee-grid { grid-template-columns: 1fr; gap: 18px; }
  .aditi .gtee-seal { width: 64px; }
  .aditi .proof-head { grid-template-columns: 38px 1fr; gap: 12px; }
  .aditi .proof-ico { width: 38px; height: 38px; }
  .aditi .q-foot { gap: 13px; }
  .aditi .q-avatar { width: 48px; }
}


/* ==========================================================================
   Deliberate design changes to the software-services page, made after
   extraction from software-services-visual.html.

   WHY THIS FILE EXISTS
   assets/css/aditi-brand.css and assets/css/aditi-visuals.css are the page's
   own stylesheets and are maintained by hand. Changes we decide on ourselves
   during the Divi conversion live here instead, and load after both, so the
   originals stay a clean record of what the page shipped with.

   Sibling of ../pilot-home/aditi-home-overrides.css. Same rule: keep every
   change commented with who asked for it and why.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Hero facts: one per line.

   Carried over from the home page (aditi-home-overrides.css). The generated
   rule is `repeat(auto-fit, minmax(240px, 1fr))`, which in the hero's half-
   width column produces 2 + 1 and reads as a mistake. A single column keeps
   the three items as a list at every width. Row gap, padding and the top
   border are inherited and left alone.
   -------------------------------------------------------------------------- */
.aditi .hero-facts { grid-template-columns: 1fr; }

/* --------------------------------------------------------------------------
   Hero heading: the clamp the home page already settled on.

   assets/css/aditi-brand.css still carries the old `.hero h1` clamp
   (max-width: 22ch, font-size: clamp(30px, 4.1vw, 50px)) that was tuned for a
   52-character short headline. The locked positioning statement is 140
   characters; at 22ch / 50px it runs to six lines and the hero panel comes out
   ~270px taller than the figure beside it.

   aditi-pages/css/aditi-home.css fixed exactly this for the home page on
   25-Aug-2026 with the values below. Copied here so the two pages' heroes
   match, which is what Dhanashri asked for.
   -------------------------------------------------------------------------- */
.aditi .hero h1 {
  max-width: 30ch;
  margin-bottom: 22px;
  font-size: clamp(26px, 3.3vw, 38px);
  line-height: 1.18;
}

/* --------------------------------------------------------------------------
   Head-column bottom margin below 980px (Divi build only).

   Divi zeroes `margin-bottom` on a row's last column below 980px
   (`.et_pb_row .et_pb_column:last-child`), and every section head here is the
   only column in its row. The original keeps the head's 36px bottom margin
   (28px below 700px, aditi-brand.css). The `.ad-head-col` class exists only in
   the Divi layout, so this rule is inert in the standalone page and only bites
   in the native build. It lives here rather than in aditi-services-map.css
   because check-native-css.js is media-query-blind and reads a plain
   restatement in the map as a cascade clash.
   -------------------------------------------------------------------------- */
@media (max-width: 980px) { .aditi .ad-head-col.et_pb_column { margin-bottom: 36px; } }
@media (max-width: 700px) { .aditi .ad-head-col.et_pb_column { margin-bottom: 28px; } }


/* ==========================================================================
   Native Divi modules, mapped onto the software-services page design.

   Sibling of ../pilot-home/aditi-native-map.css. Read that file's header for
   the reasoning; this one follows the same rules.

   THE DIFFERENCE FROM THE HOME MAP
   The home page's cards are real Divi modules (CTA, Blurb, Testimonial), so
   that map re-dresses each module's DOM. This page's nine diagrams and its six
   CSS-drawn visual clusters (fit, fears, the gate, the proof grid, the
   testimonial, the navy CTA) cannot be real modules, so each is one small Code
   module whose payload is the exact markup from software-services-visual.html.
   Inside a Code module that markup is untouched, so aditi-brand.css and
   aditi-visuals.css style it verbatim and this file barely has to reach in.
   What is left for this file: strip Divi's section/row/column chrome, scaffold
   the head blocks, the hero split, the buttons and the see-more strip, and
   answer Divi's responsive !important margins.

   LOAD ORDER
   aditi-brand.css, aditi-visuals.css, aditi-services-overrides.css, then this.
   build-native.js concatenates them in that order.

   THE CASCADE TRAP
   Every design rule is `.aditi .x`, specificity 0,2,0. This file loads last, so
   a 0,2,0 reset of ours beats the design on a tie. Resets here are scoped to
   `.ad-bare` / `.ad-*wrap` or carry `:not()` guards. check-native-css.js fails
   the build if a new one slips through.
   ========================================================================== */

/* --------------------------------------------------------------------------
   0. Import-stability contract. READ THIS.

   The home pilot looked right in the preview and then shifted when the layout
   was imported into Divi. The preview loads Divi's THEME stylesheet, but the
   live site also has Theme Customizer CSS, generated per site and emitted at ID
   specificity (`#page-container ...`), which the preview never sees.

   The theme CSS confirms Divi adds NO module bottom-margin at desktop and only
   `.et_pb_column .et_pb_module { margin-bottom: 30px }` below 980px, so module
   spacing is not the risk. The risk is the Customizer overriding:

     - section / row padding      -> forced here with !important and an
                                     #page-container copy
     - the hero and see-more column boxes (width, padding, float, stacking)
                                  -> forced off Divi's float/percent layout
     - button colour and radius   -> section 11, already #page-container-scoped

     - fonts                      -> section 0a. The Customizer sets a site
                                     heading and body font at high specificity,
                                     and Divi's static-CSS combiner drops the
                                     @import font link, so both are re-forced.
     - the multi-column grids      -> section 0b. Divi's static-CSS processor
                                     mangles the nested `@supports` inside
                                     `@media` that aditi-brand.css / aditi-
                                     visuals.css use for the subgrid card rows,
                                     which left the lanes at three-across with a
                                     stray top margin. Restated flat here.

   Everything else is a Code module: Divi passes the payload through untouched,
   so aditi-brand.css / aditi-visuals.css style it verbatim and the import has
   nothing else to disturb.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   0a. Fonts. Montserrat headings, Inter body.

   Loaded by @import on line 1, but Divi's static-CSS combiner can move our
   file below other rules and an @import that is not first is ignored, so the
   faces may not load at all. STEPS.md enqueues the Google Fonts stylesheet
   separately for that reason. Here the family is re-forced at #page-container
   so the Customizer's site fonts cannot win, with the same Arial fallback
   aditi-brand.css uses.
   -------------------------------------------------------------------------- */
/* Re-assert the custom properties and the base body font, so every
   `font-family: var(--head)` / `var(--body)` rule in aditi-brand.css and
   aditi-visuals.css resolves correctly no matter what the Customizer set on
   `body`. Those two files already put the right family on every element; this
   only stops a site-wide override from reaching them. */
#page-container .aditi {
  --head: 'Montserrat', Arial, Helvetica, sans-serif;
  --body: 'Inter', Arial, Helvetica, sans-serif;
  font-family: var(--body) !important;
}
/* The Code-module clusters are left entirely to aditi-brand.css /
   aditi-visuals.css: every element there already carries `font-family:
   var(--head)` or `var(--body)`, and the custom properties above now resolve
   correctly whatever the Customizer set on `body`. Only the real modules and
   the tag-targeted headings need forcing. */
#page-container .aditi .et_pb_text .et_pb_text_inner { font-family: var(--body) !important; }
#page-container .aditi h1, #page-container .aditi h2,
#page-container .aditi h3, #page-container .aditi h4,
#page-container .aditi .et_pb_module_heading,
#page-container .aditi .dgm text { font-family: var(--head) !important; }
#page-container .aditi .kicker .et_pb_text_inner,
#page-container .aditi .kicker .et_pb_text_inner p { font-family: var(--head) !important; }

/* --------------------------------------------------------------------------
   0b. Multi-column grids, restated flat.

   aditi-brand.css / aditi-visuals.css define these with a nested
   `@supports (grid-template-rows: subgrid)` inside `@media (min-width: 981px)`.
   Divi's static-CSS generator does not always survive a nested at-rule, and
   when it drops the block the lanes fall back to `.lanes { repeat(3, 1fr) }`
   with the subgrid's `margin-top: 34px` still on nth-child(n+3), which is the
   three-across-with-a-dropped-card bug.

   These rules are flat, carry NO nested at-rules, and load last. The lanes keep
   the coded page's subgrid (the diagram, title, strapline and DELIVERED rows
   line up across all four cards), just written without the `@supports` wrapper
   that Divi's combiner was dropping. Subgrid is supported in every browser Divi
   targets; the two-column fallback below 981px does not use it.
   -------------------------------------------------------------------------- */
/* Base: one column everywhere. Wider layouts are added by min-width queries
   below, which mirror aditi-brand.css / aditi-visuals.css exactly. */
.aditi .ad-laneswrap .lanes,
.aditi .ad-laneswrap .lanes--four,
.aditi .ad-fearswrap .fears,
.aditi .ad-proofwrap .proof,
.aditi .ad-phaseswrap .phases,
.aditi .ad-fit .fit,
.aditi .ad-ctawrap .know,
.aditi .ad-statswrap .stats {
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: none;
}
.aditi .ad-laneswrap .lanes { gap: 24px; }
.aditi .ad-fearswrap .fears { gap: 24px; }
.aditi .ad-proofwrap .proof { gap: 22px; }
.aditi .ad-proofwrap .proof-item { grid-column: auto; }
.aditi .ad-phaseswrap .phases { gap: 28px; }
.aditi .ad-fit .fit { gap: 20px; }              /* aditi-visuals: 20px on phone */
/* Below 981px the cards are one per row: a flex column with the DELIVERED foot
   pinned to the bottom. The 981px block re-declares this as subgrid. */
.aditi .ad-laneswrap .lane {
  display: flex !important;
  flex-direction: column !important;
  grid-row: auto !important;
  margin-top: 0 !important;
}
.aditi .ad-laneswrap .lane > .lane-foot { margin-top: auto; }

@media (min-width: 701px) {
  .aditi .ad-fearswrap .fears { grid-template-columns: 1fr 1fr; }
  .aditi .ad-fit .fit { grid-template-columns: 1fr 1fr; gap: 24px; }
  .aditi .ad-proofwrap .proof { grid-template-columns: repeat(2, 1fr); }
  .aditi .ad-proofwrap .proof-item--wide { grid-column: 1 / -1; }
  .aditi .ad-statswrap .stats { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 981px) {
  /* Two columns, and one shared 10-row track list (5 rows per card row) so the
     four cards' internal rows all align: diagram, title, strapline, body, foot.
     Flat subgrid, what the coded page does.

     The body row is `max-content`, not the coded page's `1fr`. Inside a Divi
     Code module the grid picks up ~124px of free space that a plain `1fr` then
     hands to the shorter card row, inflating it. `max-content` sizes the body
     row to the taller of its two cards' bodies and no more, which is what the
     `1fr` resolves to on the standalone page anyway. */
  .aditi .ad-laneswrap .lanes,
  .aditi .ad-laneswrap .lanes--four {
    grid-template-columns: repeat(2, 1fr);
    grid-template-rows: repeat(2, auto auto auto max-content auto);
    column-gap: 24px;
    row-gap: 0;
  }
  .aditi .ad-laneswrap .lane {
    display: grid !important;
    grid-row: span 5 !important;
    grid-template-rows: subgrid;
    row-gap: 0;
  }
  /* The gap between the two rows of cards rides on the second row's top margin,
     since row-gap is 0 (subgrid would otherwise space every card's internals). */
  .aditi .ad-laneswrap .lane:nth-child(n+3) { margin-top: 34px !important; }
  .aditi .ad-laneswrap .lane > .lane-foot { margin-top: 0; }

  .aditi .ad-phaseswrap .phases { grid-template-columns: repeat(3, 1fr); }
  .aditi .ad-statswrap .stats { grid-template-columns: repeat(4, 1fr); }
  .aditi .ad-ctawrap .know { grid-template-columns: repeat(3, 1fr); }
}

/* --------------------------------------------------------------------------
   1. Divi chrome removal.
   -------------------------------------------------------------------------- */
body:not(.et-fb) .aditi .ad-bare.et_pb_column,
body:not(.et-fb) .aditi .ad-bare.et_pb_image,
body:not(.et-fb) .aditi .ad-bare .et_pb_image_wrap {
  display: contents;
}

/* Rows carry the page's spacing, EXCEPT the panels (hero, navy CTA) and the
   see-more strip, which set their own padding. Forced with !important and an
   #page-container copy, because the Customizer can emit row padding at ID
   level and that is one of the things that shifted on the home import. */
.aditi .ad-row.et_pb_row:not(.panel-light):not(.navy):not(.ad-sec-more),
#page-container .aditi .ad-row.et_pb_row:not(.panel-light):not(.navy):not(.ad-sec-more) {
  padding: 0 !important;
}
.aditi .ad-row.et_pb_row { margin-left: auto; margin-right: auto; }

/* Divi clears floated columns with `.et_pb_row::after`. Inside a grid that
   pseudo-element is a phantom item. Kill it only on the rows converted to grid:
   the hero, the navy CTA and the see-more strip. Every other row keeps Divi's
   clearfix so it does not collapse. */
.aditi .ad-hero.et_pb_row::before, .aditi .ad-hero.et_pb_row::after,
.aditi .ad-sec-more.et_pb_row::before, .aditi .ad-sec-more.et_pb_row::after { content: none; }
/* The navy CTA row is NOT converted: it keeps its single floated 4_4 column and
   Divi's clearfix, and the cta-grid layout lives inside the Code module. */

/* Section rhythm. `.aditi` and `.sec` are the same element here, so
   `.aditi .sec` from aditi-brand.css never fires. Restated, with !important and
   an #page-container copy so a Customizer section-padding rule cannot move it
   (this is the value that changed on the home import). Divi's own
   `.et_pb_section` padding sits below both in specificity, so it is answered
   too. */
.aditi.sec,
#page-container .aditi.sec { padding: 64px 0 !important; }
.aditi.sec:first-of-type,
#page-container .aditi.sec:first-of-type { padding-top: 0 !important; }
.aditi.sec:last-of-type,
#page-container .aditi.sec:last-of-type { padding-bottom: 0 !important; }
.aditi.sec--panel,
#page-container .aditi.sec--panel { padding: 0 !important; }
.aditi.sec + .aditi.sec { border-top: 1px solid var(--border); }
.aditi.sec--plain + .aditi.sec--plain { border-top: 0; }
.aditi.sec--panel + .aditi.sec { border-top: 0; }

/* --------------------------------------------------------------------------
   2. Code modules holding a visual cluster.

   Divi wraps the payload in .et_pb_code > .et_pb_code_inner and adds nothing
   else. The cluster markup inside is the real thing, so it needs no help; only
   the wrapper's own box has to be neutral.
   -------------------------------------------------------------------------- */
.aditi .ad-laneswrap, .aditi .ad-fearswrap, .aditi .ad-gatewrap,
.aditi .ad-phaseswrap, .aditi .ad-statswrap, .aditi .ad-proofwrap,
.aditi .ad-quotewrap, .aditi .ad-ctawrap, .aditi .ad-fit { display: block; }

/* The gate and the phases are two Code modules in one column. aditi-visuals.css
   `.gate { margin-bottom: 36px }` (28px below 700px) styles the gate payload and
   applies as-is. Nothing to add. */

/* --------------------------------------------------------------------------
   3. Headings and body text.

   Every Heading module except the hero sits inside a `.head` column, where the
   original keeps `.head h2 { margin-bottom: 10px }` even when the h2 is last
   (section 3 has no intro line). So 10px generic; the hero heading takes 22px.
   -------------------------------------------------------------------------- */
.aditi .ad-h .et_pb_module_heading { padding-bottom: 0; margin: 0 0 10px; }
.aditi .ad-hero-h .et_pb_module_heading { margin-bottom: 22px; }
.aditi .et_pb_text > .et_pb_text_inner > p:last-child { margin-bottom: 0; }

/* Cyan underline rule on the "who we work with" heading. The original is
   `<h2 class="ruled">`; here `ruled` is on the module wrapper, so the rule is
   restated on the inner heading. Values from aditi-brand.css `.ruled`. */
.aditi .ad-ruled .et_pb_module_heading {
  display: inline-block;
  padding-bottom: 12px;
  border-bottom: 3px solid var(--cyan);
}

/* The section-3 head keeps its 14px eyebrow gap; aditi-brand.css `.head` gives
   the column its max-width and 36px bottom margin. */
.aditi .ad-head-col .kicker { margin-bottom: 14px; }

/* The fit picture (a Code module) and the two paragraphs under it. The
   paragraphs carry inline `max-width:52em` in the original; the dgm-cap also
   carries `margin-bottom:26px`. */
.aditi .ad-fitnote .et_pb_text_inner,
.aditi .ad-fitlead .et_pb_text_inner { max-width: 52em; }
.aditi .ad-fit { margin-bottom: 30px; }
.aditi .ad-fitnote { margin-bottom: 26px; }

/* --------------------------------------------------------------------------
   4. Kicker.

   A <span> in the original with margin-bottom:14px. Here a Text module whose
   text WordPress wraps in <p>, and `.aditi p` adds its own 14px, so the gap
   came out doubled. Flatten the paragraph; keep the single 14px from `.kicker`.
   Inside a `.head` the same <p> also matches `.aditi .head p` at 18px, hence
   the inherit.
   -------------------------------------------------------------------------- */
.aditi .kicker .et_pb_text_inner p {
  margin: 0;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
}
.aditi .kicker .et_pb_text_inner {
  font-family: var(--head);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--cyan-deep);
}
/* The guarantee kicker sits inside the Code cluster already, so it is not a
   module and none of the above touches it. It keeps aditi-brand.css intact. */

/* --------------------------------------------------------------------------
   5. Buttons.
   -------------------------------------------------------------------------- */
.aditi .et_pb_button_module_wrapper { display: inline-block; margin: 0 12px 0 0; }
.aditi .et_pb_button_module_wrapper:last-child { margin-right: 0; }

.aditi .ad-btn.et_pb_button::after,
#et-boc .et-l .aditi .ad-btn.et_pb_button::after { display: none !important; content: none !important; }
.aditi .ad-btn.et_pb_button:hover { padding: 15px 28px; }
.aditi .ad-btn.et_pb_button {
  transition: background .18s ease, color .18s ease, border-color .18s ease;
  /* new/style.min.css sets `.et_pb_button { line-height: 1.7em !important }`,
     which made every button 11px taller than the original. The !important is
     Divi's, so it can only be answered with !important. */
  line-height: 1 !important;
  padding: 15px 28px;
  font-size: 15px;
}

/* --------------------------------------------------------------------------
   6. Hero.

   Original split is 1.08fr / .92fr. The row is two 1_2 Divi columns forced off
   float/percent onto a grid of ours, with !important so a Customizer column
   width or a stacking rule cannot pull it back.
   -------------------------------------------------------------------------- */
.aditi .ad-hero.et_pb_row {
  display: grid;
  grid-template-columns: 1.08fr .92fr;
  column-gap: 44px;
  align-items: start;
}
.aditi .ad-hero > .et_pb_column {
  width: auto !important;
  max-width: none !important;
  margin: 0 !important;
  float: none !important;
}
.aditi .ad-hero > .ad-hero-copy { padding: 0 !important; }
/* The figure column IS the frame (aditi-visuals.css `.hero-figure`); force its
   padding so a Customizer column-padding rule cannot flatten it. */
.aditi .ad-hero > .hero-figure.et_pb_column { padding: 26px 26px 22px !important; }
@media (max-width: 980px) { .aditi .ad-hero > .hero-figure.et_pb_column { padding: 20px 20px 18px !important; } }
@media (max-width: 700px) { .aditi .ad-hero > .hero-figure.et_pb_column { padding: 16px 16px 14px !important; } }

/* The gap above the facts list stands in for `.hero .btns { margin-bottom:
   36px }` (the buttons are separate modules here). */
.aditi .ad-hero .ad-facts { margin-top: 36px; }

/* The figure frame. aditi-visuals.css `.hero-figure` supplies the border, the
   cyan base rule and the padding, and the column carries that class. */
.aditi .ad-hero-figcol .et_pb_code_inner { line-height: 0; }
.aditi .ad-hero-figcol .dgm-cap { line-height: 1.55; margin: 16px 0 0; }

/* Facts list. The original had an inline <svg> tick per item; as a background
   it stays plain editable text. Colour is --cyan-deep, #0092AF. One column,
   the same decision Dhanashri made on the home page (aditi-home-overrides). */
.aditi .ad-facts .et_pb_text_inner ul {
  display: grid;
  grid-template-columns: 1fr;
  gap: 13px 28px;
  padding-top: 24px;
  margin: 0;
  border-top: 1px solid var(--border);
  font-size: 14px;
  color: var(--mid);
  list-style: none;
}
.aditi .ad-facts .et_pb_text_inner li {
  position: relative;
  padding-left: 25px;
  line-height: 1.45;
}
.aditi .ad-facts .et_pb_text_inner li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 2px;
  width: 16px;
  height: 16px;
  background: no-repeat center/16px 16px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='m4 10.5 3.5 3.5L16 5.5' stroke='%230092AF' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   7. See-more strip. Same treatment as the home map.
   -------------------------------------------------------------------------- */
.aditi .ad-sec-more.et_pb_row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px 28px;
  margin-top: 24px;
  padding: 26px 30px !important;
  background: var(--bg-light);
  border: 1px solid var(--border);
  border-radius: 6px;
}
.aditi .ad-sec-more > .et_pb_column {
  width: auto !important;
  max-width: none !important;
  margin: 0 !important;
  padding: 0 !important;
  float: none !important;
}
.aditi .ad-more-text { flex: 1 1 22em; }
.aditi .ad-more-action { flex: 0 0 auto; }
.aditi .ad-more-b .et_pb_text_inner b {
  display: block;
  font-family: var(--head);
  font-size: 16px;
  font-weight: 600;
  color: var(--navy);
  margin-bottom: 3px;
}
.aditi .ad-more-p .et_pb_text_inner { font-size: 15px; line-height: 1.6; color: var(--mid); }

/* --------------------------------------------------------------------------
   8. Navy CTA.

   `.navy` and `.dots` are on the row, so aditi-brand.css draws the panel. The
   payload (cta-grid + the know strip) is the real markup, styled verbatim.
   Only the row's own layout box is set here.
   -------------------------------------------------------------------------- */
.aditi .ad-cta.et_pb_row > .et_pb_column {
  width: 100% !important;
  margin: 0 !important;
  padding: 0 !important;
  float: none !important;
}
.aditi .ad-ctawrap .et_pb_code_inner { display: block; }

/* --------------------------------------------------------------------------
   9. Responsive.
   -------------------------------------------------------------------------- */
@media (max-width: 980px) {
  /* Divi below 980px: `.et_pb_column { width: 100%; margin-bottom: 30px }` to
     stack, and `.et_pb_column .et_pb_module { margin-bottom: 30px }` on every
     non-last module. The design's spacing comes from the grid gaps and the
     restatements in section 3, so both of Divi's margins are cleared where
     they would otherwise stack: the hero and see-more columns, and the head
     and hero-copy modules. */
  .aditi .ad-hero > .et_pb_column,
  .aditi .ad-sec-more > .et_pb_column { margin-bottom: 0 !important; }

  .aditi .ad-head-col .et_pb_module,
  .aditi .ad-hero-copy .et_pb_module { margin-bottom: 0; }
  .aditi .ad-head-col .kicker,
  .aditi .ad-hero-copy .kicker { margin-bottom: 14px; }
  .aditi .ad-hero-copy .ad-lead { margin-bottom: 32px; }
  .aditi .ad-hero-copy .ad-facts { margin-top: 36px; }

  .aditi .ad-hero.et_pb_row { grid-template-columns: 1fr; column-gap: 0; row-gap: 28px; }
  /* aditi-visuals.css gives `.hero-figure { order: -1 }` here and the column
     carries that class, so the figure leads on a phone. */
}

/* The head column's own bottom margin below 980px is restored in
   aditi-services-overrides.css (Divi zeroes a row's last column there, the
   original keeps it; check-native-css.js is media-query-blind so a plain
   restatement in this file would read as a clash). */

@media (max-width: 700px) {
  .aditi.sec,
  #page-container .aditi.sec { padding: 44px 0 !important; }
  .aditi.sec:first-of-type { padding-top: 0 !important; }
  .aditi.sec:last-of-type { padding-bottom: 0 !important; }
  .aditi .ad-sec-more.et_pb_row { padding: 22px 20px !important; }
  /* aditi-brand.css stacks the hero buttons with `.btns .btn + .btn { margin-top: 10px }` */
  .aditi .et_pb_button_module_wrapper { display: block; width: 100%; margin: 0 0 10px; }
  .aditi .ad-sec-more .et_pb_button_module_wrapper,
  .aditi .et_pb_button_module_wrapper:last-child { margin-bottom: 0; }
  .aditi .ad-btn.et_pb_button { display: block; width: 100%; }
  /* the see-more strip wraps its button to its own full-width line */
  .aditi .ad-sec-more .ad-more-action { flex: 1 1 100%; }
}

/* --------------------------------------------------------------------------
   10. Visual Builder.
   -------------------------------------------------------------------------- */
body.et-fb .aditi .ad-bare.et_pb_column { display: block; }

/* --------------------------------------------------------------------------
   11. Front-end ID guard for button colours.

   Divi's Theme Customizer emits button colours under `#page-container`, an ID,
   which beats every plain class rule of ours. aditi-brand.css carries
   `#et-boc .et-l` pairs, but `#et-boc` only exists in the Visual Builder. On
   the live page the wrapper is `#page-container`. Values restated, not new.
   -------------------------------------------------------------------------- */
#page-container .aditi .btn--primary { background: var(--navy); border-color: var(--navy); color: var(--white); }
#page-container .aditi .btn--primary:hover { background: var(--navy-deep); border-color: var(--navy-deep); color: var(--white); }
#page-container .aditi .btn--ghost { background: transparent; border-color: var(--navy); color: var(--navy); }
#page-container .aditi .btn--ghost:hover { background: var(--navy); border-color: var(--navy); color: var(--white); }
#page-container .aditi .btn--onnavy { background: var(--white); border-color: var(--white); color: var(--navy); }
#page-container .aditi .btn--onnavy:hover { background: var(--cyan); border-color: var(--cyan); color: var(--navy); }
#page-container .aditi .btn--onnavy-line { background: transparent; border-color: rgba(255,255,255,.55); color: var(--white); }
#page-container .aditi .btn--onnavy-line:hover { border-color: var(--white); background: rgba(255,255,255,.10); color: var(--white); }

#page-container .aditi .btn { border-radius: 4px; line-height: 1; }
