/* =====================================================================
   KBJ & CO — public site.

   Rebuilt against how Indian law firms actually present themselves. The
   homepages of AZB, Trilegal, Khaitan, Cyril Amarchand, JSA, S&R and
   Luthra share a grammar: one deep house colour and one warm metal, a
   single restrained typeface family, flat surfaces, and whitespace and
   1px rules doing the work that shadows and rounded cards were doing
   here. AZB is #002346 with terracotta; S&R #00205b with maroon; Luthra
   #1a4c33 with #cfac33 gold. Not one of them ships a rounded card with a
   drop shadow, and not one of them justifies its body copy.

   What this replaces: 24 unrelated font sizes (including a 14.5px), 88
   border-radii, 52 box-shadows, 21 gradients, and a grey placeholder
   block with the letters "SC" in it standing in for a photograph.

   Everything below is built on two scales — type and space — and nothing
   is allowed off them.
   ===================================================================== */

:root {
    /* Palette. Deep ink, one navy, brass used sparingly. */
    --kbj-ink:    #101d2b;
    --kbj-navy:   #1c3d5a;
    --kbj-navy-d: #12293e;
    --kbj-brass:  #8c6f3f;
    --kbj-paper:  #f4f2ed;
    --kbj-white:  #ffffff;
    --kbj-slate:  #5d6b78;
    --kbj-line:   #ded9d0;
    --kbj-line-2: #eceae4;

    /* Serif display over sans body — the inverse of Abhimantran, so the
       two practices do not read as one. */
    --kbj-display: 'Source Serif 4', 'Iowan Old Style', Georgia, serif;
    --kbj-body:    'Inter Tight', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

    /* Type scale. Nine steps, and nothing between them. */
    --t-1:  12px;   /* eyebrows, labels, meta */
    --t-2:  13px;   /* nav, captions */
    --t-3:  15px;   /* secondary body */
    --t-4:  17px;   /* body */
    --t-5:  20px;   /* h4, list headings */
    --t-6:  24px;   /* lead, h3 */
    --t-7:  32px;   /* section h2 */
    --t-8:  clamp(30px, 4.2vw, 50px);  /* hero */

    /* Space scale. */
    --s-1: 4px;
    --s-2: 8px;
    --s-3: 12px;
    --s-4: 16px;
    --s-5: 24px;
    --s-6: 32px;
    --s-7: 48px;
    --s-8: 64px;
    --s-9: 96px;

    /* One radius, used on controls only. Surfaces are square. */
    --r: 2px;

    /* Motion. Two curves — one for states, one for travel — and five
       durations. The same discipline the type and space scales are under.

       The role names exist so the Motion block at the foot of this file
       can be byte-identical across the three sites. Only these five lines
       know which palette this one is. */
    --m-accent: var(--kbj-navy);
    --m-metal:  var(--kbj-brass);
    --m-line:   var(--kbj-line);
    --m-ink:    var(--kbj-ink);
    --m-body:   var(--kbj-body);

    --ease:      cubic-bezier(0.22, 0.61, 0.36, 1);
    --ease-expo: cubic-bezier(0.16, 1, 0.30, 1);

    --dur-1: 120ms;    /* presses, icon swaps */
    --dur-2: 220ms;    /* hover, open and close */
    --dur-3: 380ms;    /* the header lifting away */
    --dur-4: 720ms;    /* content settling into place */
    --dur-5: 1100ms;   /* type being set, images uncovering */
}

/* ---------------------------------------------------------------------
   Reset and base
   --------------------------------------------------------------------- */

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

body {
    font-family: var(--kbj-body);
    font-size: var(--t-4);
    line-height: 1.65;
    color: var(--kbj-ink);
    background: var(--kbj-white);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: left;
}

/* Ragged right, always. Justified text on the web can only stretch word
   spaces, which is what produced the rivers running down every paragraph
   on this page. No firm site surveyed justifies its copy. */
p, li, dd, blockquote {
    text-align: left;
    -webkit-hyphens: manual;
    hyphens: manual;
}

h1, h2, h3, h4, h5, h6 {
    font-family: var(--kbj-display);
    font-weight: 600;
    line-height: 1.18;
    letter-spacing: -0.012em;
    text-wrap: balance;
    color: var(--kbj-ink);
}

a {
    color: inherit;
}

img {
    max-width: 100%;
    display: block;
}

::selection {
    background: var(--kbj-navy);
    color: var(--kbj-white);
}

:focus-visible {
    outline: 2px solid var(--kbj-navy);
    outline-offset: 2px;
}

.container {
    max-width: 1240px;
    margin: 0 auto;
    padding: 0 var(--s-7);
}

/* ---------------------------------------------------------------------
   Header
   --------------------------------------------------------------------- */

.header {
    position: sticky;
    top: 0;
    z-index: 1000;
    background: var(--kbj-white);
    border-bottom: 1px solid var(--kbj-line);
}

.top-bar {
    background: var(--kbj-ink);
    color: rgba(255, 255, 255, 0.82);
    padding: var(--s-2) 0;
    font-size: var(--t-1);
    letter-spacing: 0.02em;
}

.contact-info {
    display: flex;
    gap: var(--s-5);
    justify-content: flex-end;
    flex-wrap: wrap;
}

.contact-info span {
    display: flex;
    align-items: center;
    gap: var(--s-2);
}

.contact-info a {
    text-decoration: none;
}

.contact-info a:hover {
    color: var(--kbj-white);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.navbar {
    padding: var(--s-4) 0;
}

.navbar .container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: var(--s-6);
}

.logo {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}

.logo img,
.logo-mark {
    height: 52px;
    width: auto;
}

.logo h1 {
    font-size: var(--t-6);
    font-weight: 600;
    letter-spacing: 0.01em;
    margin: 0;
}


.nav-links {
    display: flex;
    align-items: center;
    gap: var(--s-5);
    list-style: none;
}

.nav-links > li > a {
    font-family: var(--kbj-body);
    font-size: var(--t-2);
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--kbj-ink);
    text-decoration: none;
    padding: var(--s-2) 0;
    display: inline-block;
    border-bottom: 1px solid transparent;
}

/* The brass rule under a hovered link is drawn by the ::after in the
   Motion block, which wipes in from the left instead of appearing whole.
   Only the colour changes here. */
.nav-links > li > a:hover {
    color: var(--kbj-navy);
}

/* Dropdowns: a plain panel on a hairline, not a floating rounded card. */
.dropdown {
    position: relative;
}

.dropdown-menu {
    position: absolute;
    top: 100%;
    left: calc(-1 * var(--s-4));
    min-width: 280px;
    background: var(--kbj-white);
    border: 1px solid var(--kbj-line);
    border-top: 2px solid var(--kbj-navy);
    padding: var(--s-2) 0;
    list-style: none;
    z-index: 1200;
}

.dropdown-menu li a {
    display: block;
    padding: var(--s-2) var(--s-4);
    font-size: var(--t-3);
    color: var(--kbj-ink);
    text-decoration: none;
}

.dropdown-menu li a:hover {
    background: var(--kbj-paper);
    color: var(--kbj-navy);
}

.practice-areas-menu {
    columns: 2;
    column-gap: 0;
    min-width: 520px;
}

/* The portal button is an <a> inside the nav list, so `.nav-links > li > a`
   matches it too — and at one class plus two elements it outweighs a single
   class. That rule was winning colour, padding and border-bottom, which put
   near-black text on the navy ground with no horizontal padding. Matched
   here at the same depth so the button's own styling wins. */
.client-login-btn,
.nav-links > li > a.client-login-btn {
    display: inline-block;
    background: var(--kbj-navy);
    color: var(--kbj-white);
    border: 1px solid var(--kbj-navy);
    border-radius: var(--r);
    padding: 9px 18px;
    font-size: var(--t-2);
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
}

.client-login-btn:hover,
.nav-links > li > a.client-login-btn:hover {
    background: var(--kbj-navy-d);
    border-color: var(--kbj-navy-d);
}

.login-nav-item {
    margin-left: var(--s-2);
}

.menu-toggle {
    display: none;
    flex-direction: column;
    gap: 5px;
    background: none;
    border: none;
    cursor: pointer;
    padding: var(--s-2);
}

.menu-toggle span {
    display: block;
    width: 22px;
    height: 1.5px;
    background: var(--kbj-ink);
}

/* ---------------------------------------------------------------------
   Hero — one still, no carousel
   --------------------------------------------------------------------- */

.hero {
    background: var(--kbj-paper);
    border-bottom: 1px solid var(--kbj-line);
    padding: var(--s-9) 0;
}

.hero-inner {
    display: grid;
    grid-template-columns: 1fr 0.62fr;
    gap: var(--s-8);
    align-items: center;
}

.hero-statement {
    display: flex;
    flex-direction: column;
    gap: var(--s-5);
}

.hero-eyebrow {
    font-size: var(--t-1);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--kbj-brass);
    margin: 0;
}

.hero h2 {
    font-size: var(--t-8);
    font-weight: 400;
    line-height: 1.08;
    letter-spacing: -0.02em;
    margin: 0;
    max-width: 15ch;
}

.hero-sub {
    font-size: var(--t-4);
    line-height: 1.62;
    color: var(--kbj-slate);
    margin: 0;
    max-width: 54ch;
}

/* The courts are the credential — a rule-separated list, not four boxes. */
.hero-courts {
    list-style: none;
    margin: 0;
    padding: 0;
    border-top: 1px solid var(--kbj-line);
    max-width: 46ch;
}

.hero-courts li {
    font-size: var(--t-3);
    color: var(--kbj-ink);
    padding: 10px 0;
    border-bottom: 1px solid var(--kbj-line);
}

.hero-actions {
    display: flex;
    gap: var(--s-3);
    flex-wrap: wrap;
}

.hero-figure {
    margin: 0;
    background: var(--kbj-line);
    align-self: stretch;
}

.hero-figure img {
    width: 100%;
    height: 100%;
    min-height: 460px;
    object-fit: cover;
    object-position: center 26%;
}

/* ---------------------------------------------------------------------
   Buttons
   --------------------------------------------------------------------- */

.btn-primary,
.cta-button {
    display: inline-block;
    background: var(--kbj-navy);
    color: var(--kbj-white);
    border: 1px solid var(--kbj-navy);
    border-radius: var(--r);
    padding: 12px 24px;
    font-family: var(--kbj-body);
    font-size: var(--t-2);
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    text-decoration: none;
    text-align: center;
    cursor: pointer;
}

.btn-primary:hover,
.cta-button:hover {
    background: var(--kbj-navy-d);
    border-color: var(--kbj-navy-d);
}

.cta-button--quiet {
    background: transparent;
    color: var(--kbj-navy);
}

.cta-button--quiet:hover {
    background: rgba(28, 61, 90, 0.07);
    color: var(--kbj-navy-d);
    border-color: var(--kbj-navy);
}

/* A text link that reads as a link without being a button. */
.learn-more,
.doc-download {
    display: inline-block;
    font-size: var(--t-2);
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--kbj-navy);
    text-decoration: none;
    border-bottom: 1px solid var(--kbj-line);
    padding-bottom: 2px;
}

.learn-more:hover,
.doc-download:hover {
    border-bottom-color: var(--kbj-navy);
}

.section-cta {
    margin-top: var(--s-7);
}

/* ---------------------------------------------------------------------
   Section frame

   Every section opens on a full-width hairline with the heading below it
   and its standfirst set to the right — the same device Trilegal and AZB
   use to separate sections without boxing them. The centred heading with
   a 40px bar under it is gone.
   --------------------------------------------------------------------- */

.section {
    padding: var(--s-9) 0;
}

.section-header {
    border-top: 1px solid var(--kbj-line);
    padding-top: var(--s-5);
    margin-bottom: var(--s-7);
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
    gap: var(--s-6);
    align-items: baseline;
    text-align: left;
}

.section-header h2 {
    font-size: var(--t-7);
    font-weight: 400;
    letter-spacing: -0.015em;
    margin: 0;
}

.section-subtitle {
    font-size: var(--t-3);
    color: var(--kbj-slate);
    margin: 0;
    text-align: left;
}

/* The 2014 divider bar. Kept as a no-op so any page still emitting the
   element does not open a gap. */
.underline {
    display: none;
}

/* Section grounds alternate paper and white. No gradients. */
.about,
.practice-areas,
.news-reports,
.clients,
.contact {
    background: var(--kbj-white);
}

.team,
.judgements,
.public-info,
.payment {
    background: var(--kbj-paper);
}

/* ---------------------------------------------------------------------
   About / Team — running text
   --------------------------------------------------------------------- */

.about-content,
.team-content,
.clients-content {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: var(--s-8);
    align-items: start;
    text-align: left;
}

.lead {
    font-family: var(--kbj-display);
    font-size: var(--t-6);
    font-weight: 400;
    line-height: 1.35;
    letter-spacing: -0.01em;
    color: var(--kbj-ink);
    margin: 0;
    max-width: 26ch;
}

.about-body,
.team-body {
    display: flex;
    flex-direction: column;
    gap: var(--s-4);
}

.about-body p,
.team-body p {
    font-size: var(--t-4);
    line-height: 1.7;
    color: var(--kbj-slate);
    max-width: 62ch;
}

/* ---------------------------------------------------------------------
   Practice areas — a rule-separated list, not cards with initials in them
   --------------------------------------------------------------------- */

.practice-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--s-8);
    border-top: 1px solid var(--kbj-line);
}

.practice-item {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--s-4);
    padding: var(--s-5) 0;
    border-bottom: 1px solid var(--kbj-line);
}

.practice-index {
    font-size: var(--t-1);
    font-weight: 500;
    letter-spacing: 0.1em;
    color: var(--kbj-brass);
    padding-top: 5px;
    font-variant-numeric: tabular-nums;
}

.practice-item h3 {
    font-size: var(--t-5);
    font-weight: 600;
    margin: 0 0 var(--s-2);
}

.practice-item p {
    font-size: var(--t-3);
    line-height: 1.65;
    color: var(--kbj-slate);
    margin: 0;
}

/* ---------------------------------------------------------------------
   Judgements
   --------------------------------------------------------------------- */

.judgements-preview {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    gap: var(--s-8);
    align-items: start;
}

.courts-dropdown-section h3,
.recent-judgements h3 {
    font-family: var(--kbj-body);
    font-size: var(--t-1);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--kbj-brass);
    margin: 0 0 var(--s-4);
}

.courts-list {
    display: flex;
    flex-direction: column;
    border-top: 1px solid var(--kbj-line);
    background: none;
}

/* The transition belongs on the resting state, not inside :hover. Where
   it was, the indent eased in and then snapped back the instant the
   cursor left — the one piece of movement on the page, and it only
   worked in one direction. */
.court-link {
    display: block;
    padding: var(--s-3) 0;
    font-size: var(--t-3);
    color: var(--kbj-ink);
    text-decoration: none;
    border-bottom: 1px solid var(--kbj-line);
    transition:
        padding-left var(--dur-2) var(--ease),
        color var(--dur-2) var(--ease);
}

.court-link:hover {
    color: var(--kbj-navy);
    padding-left: var(--s-2);
}

.judgements-list {
    display: flex;
    flex-direction: column;
    border-top: 1px solid var(--kbj-line);
}

.judgement-item {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--s-5);
    padding: var(--s-5) 0;
    border-bottom: 1px solid var(--kbj-line);
    text-decoration: none;
    color: inherit;
}

.judgement-item:hover h4 {
    color: var(--kbj-navy);
}

.judgement-date,
.news-date,
.doc-date {
    display: block;
    font-size: var(--t-1);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--kbj-slate);
    margin-bottom: var(--s-2);
}

.judgement-item h4 {
    font-size: var(--t-5);
    font-weight: 600;
    margin: 0 0 var(--s-2);
}

.judgement-item p {
    font-size: var(--t-3);
    color: var(--kbj-slate);
    margin: 0;
    max-width: 60ch;
}

.judgement-icon {
    color: var(--kbj-line);
    flex-shrink: 0;
    padding-top: var(--s-1);
}

.judgement-item:hover .judgement-icon {
    color: var(--kbj-brass);
}

/* ---------------------------------------------------------------------
   News
   --------------------------------------------------------------------- */

.news-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--s-7) var(--s-6);
}

.news-card {
    display: flex;
    flex-direction: column;
    background: none;
}

.news-image-wrapper {
    position: relative;
    aspect-ratio: 4 / 3;
    overflow: hidden;
    background: var(--kbj-paper);
    margin-bottom: var(--s-4);
}

.news-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.news-overlay {
    position: absolute;
    left: 0;
    bottom: 0;
    background: var(--kbj-ink);
    padding: 5px 10px;
}

.news-source {
    font-size: var(--t-1);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--kbj-white);
}

.news-title {
    font-size: var(--t-5);
    font-weight: 600;
    margin: 0 0 var(--s-2);
}

.news-description {
    font-size: var(--t-3);
    color: var(--kbj-slate);
    margin: 0;
}

/* ---------------------------------------------------------------------
   Public information
   --------------------------------------------------------------------- */

.info-docs-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--s-8);
    border-top: 1px solid var(--kbj-line);
}

.info-doc-card {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    gap: var(--s-4);
    padding: var(--s-5) 0;
    border-bottom: 1px solid var(--kbj-line);
    text-decoration: none;
    color: inherit;
    background: none;
}

.doc-icon {
    color: var(--kbj-line);
    padding-top: var(--s-1);
}

.doc-icon svg {
    width: 28px;
    height: 28px;
}

.info-doc-card:hover .doc-icon {
    color: var(--kbj-brass);
}

.doc-title {
    font-size: var(--t-5);
    font-weight: 600;
    margin: 0 0 var(--s-2);
}

.info-doc-card:hover .doc-title {
    color: var(--kbj-navy);
}

.doc-description {
    font-size: var(--t-3);
    color: var(--kbj-slate);
    margin: 0 0 var(--s-3);
}

/* ---------------------------------------------------------------------
   Clients
   --------------------------------------------------------------------- */

.client-categories {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--s-7);
    border-top: 1px solid var(--kbj-line);
    margin-top: var(--s-2);
}

.category {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-4) 0;
    border-bottom: 1px solid var(--kbj-line);
    text-align: left;
}

.category-icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    color: var(--kbj-brass);
}

.category h4 {
    font-family: var(--kbj-body);
    font-size: var(--t-3);
    font-weight: 500;
    letter-spacing: 0;
    margin: 0;
    text-align: left;
}

.clients-content .text-center {
    grid-column: 1 / -1;
    text-align: left;
    margin-top: var(--s-6);
}

/* ---------------------------------------------------------------------
   Contact
   --------------------------------------------------------------------- */

.contact-wrapper {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1fr);
    gap: var(--s-8);
    align-items: start;
}

.offices h3,
.contact-form-wrapper h3 {
    font-family: var(--kbj-body);
    font-size: var(--t-1);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--kbj-brass);
    margin: 0 0 var(--s-4);
}

.office-location {
    border-top: 1px solid var(--kbj-line);
    padding-top: var(--s-4);
    margin-bottom: var(--s-5);
}

.office-location h4 {
    font-size: var(--t-5);
    font-weight: 600;
    margin: 0 0 var(--s-3);
}

.office-location p {
    font-size: var(--t-3);
    color: var(--kbj-slate);
    margin: 0 0 var(--s-3);
    line-height: 1.7;
}

.office-location a {
    color: var(--kbj-navy);
    text-decoration: none;
    border-bottom: 1px solid var(--kbj-line);
}

.office-location a:hover {
    border-bottom-color: var(--kbj-navy);
}

.office-map iframe {
    display: block;
    width: 100%;
    border: 1px solid var(--kbj-line);
    filter: grayscale(1);
}

.office-map iframe:hover {
    filter: none;
}

.contact-form {
    display: flex;
    flex-direction: column;
    gap: var(--s-4);
}

.form-group {
    display: flex;
    flex-direction: column;
}

.contact-form input,
.contact-form textarea,
.payment-form input,
.payment-form textarea,
.payment-form select {
    font-family: var(--kbj-body);
    font-size: var(--t-3);
    color: var(--kbj-ink);
    background: var(--kbj-white);
    border: 1px solid var(--kbj-line);
    border-radius: var(--r);
    padding: 13px 14px;
    width: 100%;
}

.contact-form input::placeholder,
.contact-form textarea::placeholder {
    color: #98a3ad;
}

.contact-form input:focus,
.contact-form textarea:focus {
    outline: none;
    border-color: var(--kbj-navy);
}

.contact-form textarea {
    resize: vertical;
    min-height: 140px;
}

.contact-form button {
    align-self: flex-start;
}

/* ---------------------------------------------------------------------
   Payment
   --------------------------------------------------------------------- */

.payment-wrapper {
    max-width: 620px;
}

/* ---------------------------------------------------------------------
   Footer
   --------------------------------------------------------------------- */

.footer {
    background: var(--kbj-ink);
    color: rgba(255, 255, 255, 0.72);
}

.footer-content {
    padding: var(--s-9) 0 var(--s-8);
}

.footer-grid {
    display: grid;
    grid-template-columns: 1.3fr 1fr 1fr 1.2fr;
    gap: var(--s-7);
}

.footer-section h3 {
    font-family: var(--kbj-body);
    font-size: var(--t-1);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--kbj-brass);
    margin: 0 0 var(--s-4);
}

.footer-section > p {
    font-size: var(--t-3);
    color: rgba(255, 255, 255, 0.66);
    max-width: 34ch;
}

.footer-section ul {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: var(--s-2);
}

.footer-section li {
    font-size: var(--t-3);
    color: rgba(255, 255, 255, 0.66);
}

.footer-section a {
    color: rgba(255, 255, 255, 0.78);
    text-decoration: none;
}

.footer-section a:hover {
    color: var(--kbj-white);
    text-decoration: underline;
    text-underline-offset: 3px;
}

.social-links {
    display: flex;
    gap: var(--s-4);
    margin-bottom: var(--s-4);
}

.social-link {
    font-size: var(--t-2);
    letter-spacing: 0.06em;
    color: rgba(255, 255, 255, 0.6);
}

.contact-quick p {
    font-size: var(--t-3);
    color: rgba(255, 255, 255, 0.66);
    margin-bottom: var(--s-2);
    line-height: 1.6;
}

.contact-quick strong {
    color: rgba(255, 255, 255, 0.9);
    font-weight: 500;
}

.footer-bottom {
    border-top: 1px solid rgba(255, 255, 255, 0.12);
    padding: var(--s-5) 0;
}

.footer-bottom p {
    font-size: var(--t-2);
    color: rgba(255, 255, 255, 0.5);
}

/* Floating call/WhatsApp buttons — square, quiet, no bounce. */
.floating-actions {
    position: fixed;
    right: var(--s-5);
    bottom: var(--s-5);
    display: flex;
    flex-direction: column;
    gap: var(--s-2);
    z-index: 900;
}

.float-btn {
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--kbj-ink);
    color: var(--kbj-white);
    border-radius: var(--r);
    text-decoration: none;
}

.float-btn:hover {
    background: var(--kbj-navy);
}

.float-btn svg {
    width: 20px;
    height: 20px;
}

/* ---------------------------------------------------------------------
   Loading and empty states
   --------------------------------------------------------------------- */

.loading,
.no-data,
.no-data-message {
    font-size: var(--t-3);
    color: var(--kbj-slate);
    padding: var(--s-5) 0;
    border-top: 1px solid var(--kbj-line);
}

/* ---------------------------------------------------------------------
   Disclaimer
   --------------------------------------------------------------------- */

.disclaimer-overlay {
    position: fixed;
    inset: 0;
    background: rgba(16, 29, 43, 0.94);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--s-5);
    z-index: 5000;
}

.disclaimer-modal,
.disclaimer-popup {
    background: var(--kbj-white);
    border-top: 3px solid var(--kbj-brass);
    max-width: 640px;
    width: 100%;
    padding: var(--s-7);
    max-height: 88vh;
    overflow-y: auto;
}

.disclaimer-firm {
    font-size: var(--t-1);
    font-weight: 600;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--kbj-brass);
    margin: 0 0 var(--s-3);
}

.disclaimer-modal h2,
.disclaimer-popup h2 {
    font-size: var(--t-6);
    font-weight: 600;
    margin-bottom: var(--s-4);
}

.disclaimer-modal p,
.disclaimer-popup p {
    font-size: var(--t-3);
    color: var(--kbj-slate);
    margin-bottom: var(--s-3);
    line-height: 1.7;
}

.disclaimer-actions,
.disclaimer-buttons {
    display: flex;
    gap: var(--s-3);
    margin-top: var(--s-5);
    flex-wrap: wrap;
}

/* ---------------------------------------------------------------------
   Responsive
   --------------------------------------------------------------------- */

@media (max-width: 1024px) {
    .container {
        padding: 0 var(--s-6);
    }

    .news-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .footer-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--s-6);
    }
}

@media (max-width: 880px) {
    .section {
        padding: var(--s-8) 0;
    }

    .hero {
        padding: var(--s-7) 0 var(--s-8);
    }

    .hero-inner {
        grid-template-columns: 1fr;
        gap: var(--s-6);
    }

    .hero h2 {
        max-width: none;
    }

    .hero-figure {
        order: -1;
    }

    .hero-figure img {
        min-height: 0;
        height: 240px;
    }

    .section-header,
    .about-content,
    .team-content,
    .clients-content,
    .judgements-preview,
    .contact-wrapper,
    .practice-list,
    .info-docs-grid,
    .client-categories {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--s-5);
    }

    .about-content,
    .team-content,
    .judgements-preview,
    .contact-wrapper {
        gap: var(--s-6);
    }

    .lead {
        max-width: none;
    }

    /* Nav collapses to a panel under the bar. */
    .menu-toggle {
        display: flex;
    }

    .nav-links {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 0;
        background: var(--kbj-white);
        border-top: 1px solid var(--kbj-line);
        border-bottom: 1px solid var(--kbj-line);
        padding: var(--s-2) var(--s-6) var(--s-5);
    }

    .nav-links.active {
        display: flex;
    }

    .nav-links > li > a {
        padding: var(--s-3) 0;
        border-bottom: 1px solid var(--kbj-line-2);
        width: 100%;
    }

    .navbar {
        position: relative;
    }

    .dropdown-menu,
    .practice-areas-menu {
        position: static;
        min-width: 0;
        columns: 1;
        border: none;
        border-left: 2px solid var(--kbj-line);
        padding: 0 0 var(--s-2) var(--s-4);
    }

    .login-nav-item {
        margin: var(--s-3) 0 0;
    }

    .contact-info {
        justify-content: flex-start;
        gap: var(--s-4);
    }
}

@media (max-width: 640px) {
    .container {
        padding: 0 var(--s-5);
    }

    .news-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .footer-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .judgement-item {
        flex-direction: column;
        gap: var(--s-3);
    }
}

/* ---------------------------------------------------------------------
   Form states — contact and payment

   These are all that survived from the old portal block: 95 of its 111
   classes were dead, the portal and admin having been rebuilt against
   admin/admin.css. main.css is now the public site's stylesheet only.
   --------------------------------------------------------------------- */

/* Honeypot. Positioned off-screen rather than display:none, because bots
   commonly skip fields that are explicitly hidden. */
.hp-field {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.field-error {
    display: block;
    margin-top: var(--s-2);
    color: #a5281b;
    font-size: var(--t-2);
}

.contact-form input[aria-invalid="true"],
.contact-form textarea[aria-invalid="true"] {
    border-color: #a5281b;
}

.form-status {
    padding: var(--s-4);
    border-radius: var(--r);
    margin-bottom: var(--s-4);
    font-size: var(--t-3);
    line-height: 1.65;
}

.form-status--error {
    background: #fdf1ef;
    border-left: 2px solid #a5281b;
    color: #a5281b;
}

.form-status--success {
    background: var(--kbj-paper);
    border-left: 2px solid var(--kbj-brass);
    color: var(--kbj-ink);
}

.form-status--success strong {
    display: block;
    margin-bottom: var(--s-2);
    font-size: var(--t-4);
    font-weight: 600;
}

.form-status--success p {
    margin: 0 0 var(--s-4);
    color: var(--kbj-slate);
}

.form-status code {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    font-size: var(--t-2);
    background: rgba(0, 0, 0, 0.06);
    padding: 2px 6px;
    border-radius: var(--r);
}

.contact-form button[disabled],
.payment-form button[disabled] {
    opacity: 0.55;
    cursor: not-allowed;
}

.payment-form .form-group {
    margin-bottom: var(--s-4);
}

/* Rupee sign sits inside the field, so the symbol and the typed amount
   read as one control. */
.amount-group {
    position: relative;
}

.amount-group .currency-prefix {
    position: absolute;
    left: 14px;
    top: 50%;
    transform: translateY(-50%);
    font-size: var(--t-3);
    color: var(--kbj-slate);
    pointer-events: none;
}

.amount-group input {
    padding-left: 32px;
}

/* Hide the number spinners — they encourage clicking rather than typing an
   exact figure, and look out of place on a payment field. */
.amount-group input::-webkit-outer-spin-button,
.amount-group input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.amount-group input[type="number"] {
    -moz-appearance: textfield;
    appearance: textfield;
}

.payment-note {
    margin-top: var(--s-4);
    font-size: var(--t-2);
    color: var(--kbj-slate);
    line-height: 1.6;
}

/* ---------------------------------------------------------------------
   Inner pages

   judgements.html, news.html and public-info.html each carried 150–250
   lines of their own <style> block — a second, slightly different design
   system per page, with 64px titles and 24px rounded cards. They now use
   the classes below, served from this file, so a change to the house style
   reaches them too.
   --------------------------------------------------------------------- */

.page {
    padding: var(--s-8) 0 var(--s-9);
}

.back-link {
    display: inline-block;
    font-size: var(--t-2);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--kbj-slate);
    text-decoration: none;
    margin-bottom: var(--s-6);
}

.back-link:hover {
    color: var(--kbj-navy);
}

.page-head {
    border-top: 1px solid var(--kbj-line);
    padding-top: var(--s-5);
    margin-bottom: var(--s-7);
}

.page-title {
    font-size: var(--t-7);
    font-weight: 400;
    letter-spacing: -0.015em;
    margin: 0 0 var(--s-2);
}

.page-lede {
    font-size: var(--t-3);
    color: var(--kbj-slate);
    margin: 0;
    max-width: 60ch;
}

.back-button {
    background: none;
    border: none;
    font-family: var(--kbj-body);
    font-size: var(--t-2);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--kbj-slate);
    cursor: pointer;
    padding: 0;
    margin-bottom: var(--s-6);
}

.back-button:hover {
    color: var(--kbj-navy);
}

/* Court index */
.court-item {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--s-4);
    padding: var(--s-4) 0;
    border-bottom: 1px solid var(--kbj-line);
    cursor: pointer;
}

.court-item:hover .court-name {
    color: var(--kbj-navy);
}

.court-name {
    font-size: var(--t-5);
    font-family: var(--kbj-display);
}

.pdf-count {
    font-size: var(--t-1);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--kbj-slate);
    white-space: nowrap;
}

/* Document lists */
.pdfs-list {
    border-top: 1px solid var(--kbj-line);
}

.pdf-card {
    padding: var(--s-5) 0;
    border-bottom: 1px solid var(--kbj-line);
}

.pdf-header {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--s-5);
    margin-bottom: var(--s-2);
}

.pdf-title {
    font-size: var(--t-5);
    font-weight: 600;
    margin: 0;
}

.pdf-date {
    font-size: var(--t-1);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--kbj-slate);
    white-space: nowrap;
}

.pdf-description {
    font-size: var(--t-3);
    color: var(--kbj-slate);
    margin: 0 0 var(--s-3);
    max-width: 70ch;
}

.pdf-link {
    display: inline-block;
    font-size: var(--t-2);
    font-weight: 500;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--kbj-navy);
    text-decoration: none;
    border-bottom: 1px solid var(--kbj-line);
    padding-bottom: 2px;
}

.pdf-link:hover {
    border-bottom-color: var(--kbj-navy);
}

.page-empty {
    padding: var(--s-7) 0;
    font-size: var(--t-3);
    color: var(--kbj-slate);
    border-top: 1px solid var(--kbj-line);
}

/* Practice area pages */
.practice-page-hero {
    background: var(--kbj-ink);
    color: var(--kbj-white);
    padding: var(--s-9) 0;
}

.practice-page-hero .page-eyebrow {
    font-size: var(--t-1);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--kbj-brass);
    margin: 0 0 var(--s-4);
}

.practice-page-hero h1 {
    font-size: var(--t-8);
    font-weight: 400;
    line-height: 1.08;
    letter-spacing: -0.02em;
    color: var(--kbj-white);
    margin: 0 0 var(--s-4);
    max-width: 18ch;
}

.practice-page-hero p {
    font-size: var(--t-4);
    color: rgba(255, 255, 255, 0.72);
    margin: 0;
    max-width: 58ch;
}

.practice-body {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
    gap: var(--s-8);
    align-items: start;
}

.practice-body h2 {
    font-size: var(--t-6);
    font-weight: 400;
    margin: 0;
}

.practice-prose {
    display: flex;
    flex-direction: column;
    gap: var(--s-4);
}

.practice-prose p {
    font-size: var(--t-4);
    line-height: 1.7;
    color: var(--kbj-slate);
    max-width: 62ch;
}

.matter-list {
    list-style: none;
    border-top: 1px solid var(--kbj-line);
    margin: 0;
    padding: 0;
}

.matter-list li {
    font-size: var(--t-3);
    padding: var(--s-3) 0;
    border-bottom: 1px solid var(--kbj-line);
    color: var(--kbj-ink);
}

.statute-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--s-2);
}

.statute-list li {
    font-size: var(--t-3);
    color: var(--kbj-slate);
}

@media (max-width: 880px) {
    .practice-body {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--s-6);
    }

    .practice-page-hero {
        padding: var(--s-8) 0;
    }
}

/* ---------------------------------------------------------------------
   Legal pages — privacy notice, terms of use, refunds

   Long-form running text, which nothing else on these sites is. One
   column at a readable measure, headings off the same type scale as
   everything above, and the TO CONFIRM blocks set so that they cannot be
   published by accident.
   --------------------------------------------------------------------- */

.legal-prose {
    max-width: 68ch;
    padding-bottom: var(--s-9);
}

.legal-prose h2 {
    font-size: var(--t-6);
    font-weight: 600;
    margin: var(--s-8) 0 var(--s-4);
    padding-top: var(--s-5);
    border-top: 1px solid var(--m-line);
}

.legal-prose h3 {
    font-family: var(--m-body);
    font-size: var(--t-1);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--m-metal);
    margin: var(--s-6) 0 var(--s-3);
}

.legal-prose p {
    font-size: var(--t-4);
    line-height: 1.75;
    margin-bottom: var(--s-4);
}

.legal-prose ul {
    margin: 0 0 var(--s-4) var(--s-5);
}

.legal-prose li {
    font-size: var(--t-4);
    line-height: 1.75;
    margin-bottom: var(--s-2);
}

.legal-prose a {
    color: var(--m-accent);
    text-decoration: none;
    border-bottom: 1px solid var(--m-line);
    transition: border-color var(--dur-2) var(--ease);
}

.legal-prose a:hover {
    border-bottom-color: var(--m-accent);
}

/* Deliberately loud. Each of these marks a decision the firm has to make —
   a retention period, a grievance contact, the refund terms — that cannot
   be derived from the code, and the page must not read as finished while
   one is still standing. */
.legal-confirm {
    background: #fdf6e6;
    border-left: 3px solid #a5281b;
    padding: var(--s-4) var(--s-5);
    margin: var(--s-4) 0 var(--s-5);
    font-size: var(--t-3) !important;
    line-height: 1.7 !important;
    color: #6b3a10;
}

.legal-confirm strong {
    color: #a5281b;
    letter-spacing: 0.06em;
}

/* Footer legal row */
.footer-legal {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-4);
    margin-top: var(--s-3);
    list-style: none;
}

.footer-legal a {
    font-size: var(--t-2);
    color: rgba(255, 255, 255, 0.6);
    text-decoration: none;
}

.footer-legal a:hover {
    color: #fff;
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* Whether the bill has been paid, said on its face. Without it a settled
   invoice and an outstanding one were the same document. */
.inv-status {
    display: inline-block;
    margin: var(--s-3) 0 0;
    padding: 4px 12px;
    font-family: var(--m-body);
    font-size: var(--t-1);
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.inv-status.is-paid {
    background: #1f4d33;
    color: #fff;
}

.inv-status.is-part {
    background: #fdf6e6;
    color: #6b3a10;
    border-left: 2px solid #a8761a;
    letter-spacing: 0.06em;
}

.inv-status.is-cancelled {
    background: #f2f1ee;
    color: #6b6b6b;
    text-decoration: line-through;
}

/* ---------------------------------------------------------------------
   The tax invoice

   A document, not a page: no site chrome, no motion, and laid out for A4
   as much as for a screen. Half the time it will be read on paper, and
   the other half as a PDF that a browser made from this stylesheet.
   --------------------------------------------------------------------- */

.invoice-page {
    background: #f2f1ee;
    padding: var(--s-6) var(--s-4);
}

.inv-sheet {
    max-width: 820px;
    margin: 0 auto;
    background: #fff;
    padding: var(--s-8);
    border: 1px solid var(--m-line);
}

/* The one thing on the page that must not be missed: a document that
   claims to be a tax invoice while missing what makes it one. */
.inv-warning {
    background: #fdf1ef;
    border-left: 3px solid #a5281b;
    padding: var(--s-4) var(--s-5);
    margin-bottom: var(--s-6);
}

.inv-warning strong {
    display: block;
    color: #a5281b;
    margin-bottom: var(--s-2);
    letter-spacing: 0.04em;
}

.inv-warning p {
    font-size: var(--t-3);
    color: #6b3a10;
    margin: 0;
}

.inv-header {
    border-bottom: 2px solid var(--m-ink);
    padding-bottom: var(--s-4);
    margin-bottom: var(--s-6);
}

.inv-doctype {
    font-size: var(--t-1);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--m-metal);
    margin: 0 0 var(--s-2);
}

.inv-number {
    font-size: var(--t-7);
    font-weight: 600;
    margin: 0;
    letter-spacing: -0.01em;
}

.inv-parties {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s-7);
    margin-bottom: var(--s-6);
}

.inv-party h3 {
    font-family: var(--m-body);
    font-size: var(--t-1);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--m-metal);
    margin: 0 0 var(--s-3);
}

.inv-party p {
    font-size: var(--t-3);
    line-height: 1.6;
    margin: 0;
}

.inv-party-name {
    font-weight: 600;
    font-size: var(--t-4) !important;
    margin-bottom: var(--s-1) !important;
}

.inv-gstin {
    margin-top: var(--s-2) !important;
    font-variant-numeric: tabular-nums;
}

.inv-meta {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--s-4);
    border-top: 1px solid var(--m-line);
    border-bottom: 1px solid var(--m-line);
    padding: var(--s-4) 0;
    margin-bottom: var(--s-6);
}

.inv-meta-label {
    display: block;
    font-size: var(--t-1);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--m-metal);
    margin-bottom: var(--s-1);
}

.inv-meta-value {
    display: block;
    font-size: var(--t-3);
}

.inv-table-wrap {
    overflow-x: auto;
    margin-bottom: var(--s-6);
}

.inv-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--t-3);
}

.inv-table caption {
    text-align: left;
    font-family: var(--m-body);
    font-size: var(--t-1);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--m-metal);
    padding-bottom: var(--s-3);
}

.inv-table th {
    text-align: left;
    font-family: var(--m-body);
    font-size: var(--t-1);
    font-weight: 600;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    border-bottom: 1px solid var(--m-ink);
    padding: var(--s-2) var(--s-3) var(--s-2) 0;
}

.inv-table td {
    padding: var(--s-3) var(--s-3) var(--s-3) 0;
    border-bottom: 1px solid var(--m-line);
    vertical-align: top;
}

.inv-table .is-num {
    text-align: right;
    padding-right: 0;
    font-variant-numeric: tabular-nums;
}

.inv-totals {
    margin-left: auto;
    max-width: 340px;
}

.inv-total-row {
    display: flex;
    justify-content: space-between;
    gap: var(--s-5);
    padding: var(--s-2) 0;
    font-size: var(--t-3);
    border-bottom: 1px solid var(--m-line);
}

.inv-total-row.is-grand {
    font-size: var(--t-5);
    font-weight: 600;
    border-bottom: 2px solid var(--m-ink);
    padding-top: var(--s-3);
}

.inv-total-row .is-num {
    font-variant-numeric: tabular-nums;
}

.inv-words {
    margin: var(--s-5) 0 var(--s-6);
    font-size: var(--t-3);
    font-style: italic;
    color: var(--m-ink);
}

/* Rule 46(p). An invoice showing no GST is correct only if it says why. */
.inv-statement {
    border-left: 2px solid var(--m-metal);
    padding: var(--s-3) var(--s-4);
    margin-bottom: var(--s-6);
    font-size: var(--t-3);
    line-height: 1.7;
}

.inv-notes h3 {
    font-family: var(--m-body);
    font-size: var(--t-1);
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--m-metal);
    margin: 0 0 var(--s-2);
}

.inv-notes p {
    font-size: var(--t-3);
    line-height: 1.7;
    margin-bottom: var(--s-6);
}

.inv-foot {
    margin-top: var(--s-8);
    padding-top: var(--s-5);
    border-top: 1px solid var(--m-line);
    text-align: right;
}

.inv-foot p {
    font-size: var(--t-3);
    margin: 0;
}

.inv-sign {
    margin-top: var(--s-8) !important;
    color: var(--m-metal);
    font-size: var(--t-1) !important;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.inv-actions {
    margin-top: var(--s-6);
    padding-top: var(--s-5);
    border-top: 1px solid var(--m-line);
}

@media (max-width: 640px) {
    .inv-sheet {
        padding: var(--s-5);
    }

    .inv-parties,
    .inv-meta {
        grid-template-columns: 1fr;
        gap: var(--s-4);
    }
}

/* On paper: no furniture, no ground, and nothing that costs ink without
   saying anything. */
@media print {
    .invoice-page {
        background: #fff;
        padding: 0;
    }

    .inv-sheet {
        max-width: none;
        border: none;
        padding: 0;
    }

    .inv-actions {
        display: none;
    }

    .inv-table {
        page-break-inside: auto;
    }

    .inv-table tr {
        page-break-inside: avoid;
    }

    .inv-totals,
    .inv-statement,
    .inv-foot {
        page-break-inside: avoid;
    }

    @page {
        margin: 16mm;
    }
}

/* =====================================================================
   Motion

   Everything above this line drew a still page. In 1,700 lines there was
   one `transition`, and it was written inside a :hover rule so it only
   worked on the way in. Every other state change cut: hovers, dropdowns,
   the mobile menu, the disclaimer. The layout is responsive — it has been
   since the breakpoints above — but nothing in it responded.

   The vocabulary here is the one the large brand sites use, which is
   smaller than it looks. Four devices do nearly all the work:

     - Type arrives a line at a time, each line travelling up from behind
       a mask, so a heading reads as being set rather than as appearing.
     - Images unmask rather than fade, and the large ones drift against
       the scroll, which is what gives a flat page depth.
     - One column holds still while the column beside it scrolls.
     - The furniture gets out of the way: the header lifts off on the way
       down and returns the instant you go up.

   None of it needs a shadow, a gradient or a rounded corner, which is why
   it can sit under a grammar built on hairlines and whitespace. It is all
   opacity, translation and clip.

   Deliberately at the foot of the file rather than threaded through it,
   so that what moves on these sites can be read in one place and removed
   in one deletion.

   Three constraints:

     - Opacity, translation and clip only. Nothing spins or bounces, and
       nothing scales except a thumbnail under the cursor. A litigation
       practice's homepage should not feel like it is pitching.
     - Anything that hides content is gated on `html.js-motion`, which
       scripts/motion.js adds and only after confirming the visitor has
       not asked for reduced motion. No script, no hiding.
     - Reduced motion is honoured twice: the script returns early, and the
       media query at the end of this block is a backstop for any
       animation that reaches the page another way.

   The block is byte-identical across the three sites. It refers to
   --m-accent, --m-metal, --m-line and --m-ink, which each site's :root
   points at its own palette.
   ===================================================================== */

/* ---------------------------------------------------------------------
   Type set a line at a time

   scripts/motion.js measures each heading as it actually wrapped and
   rebuilds it one block per line: .m-line clips, .m-line-i starts below
   the clip and travels up. Stagger the inner spans and the heading reads
   as being typeset rather than as being faded in.

   Nothing here applies until that script has run, and the words are left
   intact — in order, separated by real spaces — so selecting the heading
   and reading it aloud both still work.
   --------------------------------------------------------------------- */

/* The measure pass wraps each word in an <i>, which is italic by default.
   Italic metrics wrap differently, and the whole point of the pass is to
   record where the line actually broke. */
.m-w {
    font-style: inherit;
    font-weight: inherit;
}

.js-motion [data-lines] .m-line {
    display: block;
    overflow: hidden;
    /* Clipping a line at its exact box shears the descenders off g, y and
       p. Pad the clip and pull the next line back up by the same amount,
       so the leading is unchanged. */
    padding-bottom: 0.14em;
    margin-bottom: -0.14em;
}

.js-motion [data-lines] .m-line-i {
    display: block;
    transform: translateY(115%);
}

.js-motion [data-lines].is-revealed .m-line-i {
    transform: none;
    transition: transform var(--dur-5) var(--ease-expo) calc(var(--m-i, 0) * 90ms);
}

/* ---------------------------------------------------------------------
   Images uncover

   A photograph that fades in announces that it was loading. One that is
   uncovered reads as having been there. The wipe runs bottom to top over
   a beat longer than the type, because it is the larger object.
   --------------------------------------------------------------------- */

.js-motion [data-unmask] {
    clip-path: inset(0 0 100% 0);
}

.js-motion [data-unmask].is-revealed {
    clip-path: inset(0 0 0 0);
    transition: clip-path var(--dur-5) var(--ease-expo);
}

/* ---------------------------------------------------------------------
   Parallax

   The four photographs are 832x1248 — portrait, in a landscape frame.
   That was a problem for the carousel this site used to run, which
   cropped them to a horizontal band and showed a strip of each. Here it
   is the point: the overflow is the room the image needs to travel
   through.

   CSS oversizes the image and centres the surplus; the script only
   translates it, and never further than the surplus allows, so no edge
   can be pulled into frame.
   --------------------------------------------------------------------- */

.m-parallax {
    will-change: transform;
}

.hero-figure {
    overflow: hidden;
}

.js-motion .hero-figure img {
    height: 128%;
    margin-top: -14%;
}

/* ---------------------------------------------------------------------
   Reveal

   The plain treatment, for everything that is neither a heading nor a
   photograph. The resting state carries no transition; the transition
   lives on .is-revealed, so content moves in and never moves back out —
   an element that leaves the viewport stays where it is.

   --reveal-delay is set per element by the script, staggered against its
   own parent.
   --------------------------------------------------------------------- */

.js-motion [data-reveal] {
    opacity: 0;
    transform: translateY(14px);
}

.js-motion [data-reveal].is-revealed {
    opacity: 1;
    transform: none;
    transition:
        opacity var(--dur-4) var(--ease-expo) var(--reveal-delay, 0ms),
        transform var(--dur-4) var(--ease-expo) var(--reveal-delay, 0ms);
}

/* ---------------------------------------------------------------------
   One column holds still

   The three two-column sections already put the short statement on the
   left and the long body on the right, and already align both to the
   top. Pinning the left column is a single property, and it is the
   difference between a page that scrolls and a page that reads.

   Not below 880px, where the two columns are stacked and there is
   nothing to hold still against.
   --------------------------------------------------------------------- */

@media (min-width: 881px) {
    .about-content .lead,
    .team-content .lead,
    .clients-content .lead,
    .judgements-preview .courts-dropdown-section,
    .contact-wrapper .offices {
        position: sticky;
        /* Clears the condensed header with a line of air under it. */
        top: 124px;
    }
}

/* ---------------------------------------------------------------------
   The chapter break

   A full-bleed photograph between two sections, drifting against the
   scroll, with the firm's name set small in the corner. It carries no
   claim and says nothing the header does not already say — it is a
   breath, and the one place on these sites where an image is allowed to
   be the whole width of the screen.
   --------------------------------------------------------------------- */

.band {
    position: relative;
    height: 56vh;
    min-height: 300px;
    max-height: 540px;
    overflow: hidden;
    background: var(--m-ink);
    border-top: 1px solid var(--m-line);
    border-bottom: 1px solid var(--m-line);
}

.band-figure {
    position: absolute;
    inset: 0;
    margin: 0;
    overflow: hidden;
}

.band-figure img {
    width: 100%;
    height: 128%;
    margin-top: -14%;
    object-fit: cover;
    object-position: center 28%;
    /* Held back so the label stays legible against any part of the frame,
       without a scrim gradient over the top of it. */
    opacity: 0.58;
}

.band-inner {
    position: relative;
    height: 100%;
    display: flex;
    align-items: flex-end;
    padding-bottom: var(--s-7);
}

.band-line {
    margin: 0;
    font-family: var(--m-body);
    font-size: var(--t-1);
    font-weight: 500;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.92);
    padding-left: var(--s-4);
    border-left: 2px solid var(--m-metal);
}

@media (max-width: 880px) {
    .band {
        height: 40vh;
        min-height: 220px;
    }

    .band-inner {
        padding-bottom: var(--s-6);
    }
}

/* ---------------------------------------------------------------------
   Header

   Three behaviours. Past the first screen the contact bar folds away and
   the navbar tightens, which returns about 46px of reading height — on a
   phone, close to two lines of body copy. Keep going down and the whole
   header lifts off; turn around and it is back, because going up is how
   you ask for the navigation. A hairline across its foot tracks progress
   through the document.

   All three are driven by classes and a custom property on <html>, set by
   the script, so the standalone pages get them without sharing the React
   header.
   --------------------------------------------------------------------- */

.header {
    transition:
        transform var(--dur-3) var(--ease-expo),
        border-color var(--dur-2) var(--ease);
}

.is-header-lifted .header {
    transform: translateY(-100%);
}

/* Lifting the header while the stacked menu is open would take the menu
   with it — it is positioned inside the header. */
.header:has(.nav-links.active) {
    transform: none;
}

/* Collapsed with grid rather than max-height. The contact line wraps to
   two lines on a narrow phone, so any fixed max-height either clips the
   email address or spends the first third of the animation travelling
   through empty space. 1fr → 0fr measures the content instead. Browsers
   that will not interpolate it simply cut, which is what the bar did
   before this block existed. */
.top-bar {
    display: grid;
    grid-template-rows: 1fr;
    transition:
        grid-template-rows var(--dur-2) var(--ease),
        padding var(--dur-2) var(--ease),
        opacity var(--dur-1) var(--ease);
}

.top-bar > .container {
    overflow: hidden;
}

.is-scrolled .top-bar {
    grid-template-rows: 0fr;
    padding-top: 0;
    padding-bottom: 0;
    opacity: 0;
}

.navbar {
    transition: padding var(--dur-2) var(--ease);
}

.is-scrolled .navbar {
    padding: var(--s-2) 0;
}

.logo img,
.logo-mark {
    transition: height var(--dur-2) var(--ease);
}

.is-scrolled .logo img,
.is-scrolled .logo-mark {
    height: 42px;
}

/* Progress. Sits on the header's own bottom rule rather than adding a
   second line to the page. Unset --m-progress scales to nothing, so a
   page whose script never ran shows no bar at all. */
.js-motion .header::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 2px;
    background: var(--m-metal);
    transform: scaleX(var(--m-progress, 0));
    transform-origin: left center;
    pointer-events: none;
}

/* The header is sticky, so an anchor that lands a section flush with the
   viewport top lands it underneath the header. This is what the smooth
   scroll in index.tsx and every #link in the bar have been doing. */
section[id],
[id].section {
    scroll-margin-top: 96px;
}

/* ---------------------------------------------------------------------
   Navigation

   The bar's hover was a 1px border switching colour in one frame. Same
   endpoint, drawn as a wipe from the left, and reused for the current
   section — which the bar previously did not indicate at all.
   --------------------------------------------------------------------- */

.nav-links > li > a {
    position: relative;
    transition: color var(--dur-2) var(--ease);
}

.nav-links > li > a::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -1px;
    height: 1px;
    background: var(--m-metal);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--dur-2) var(--ease);
}

.nav-links > li > a:hover::after,
.nav-links > li > a[aria-current='true']::after {
    transform: scaleX(1);
}

.nav-links > li > a[aria-current='true'] {
    color: var(--m-accent);
}

/* The portal button carries its own ground; a rule under it would read as
   an underlined button. */
.nav-links > li > a.client-login-btn::after {
    content: none;
}

.dropdown-menu {
    animation: m-menu-in var(--dur-2) var(--ease) both;
}

.dropdown-menu li a {
    transition:
        background-color var(--dur-1) var(--ease),
        color var(--dur-1) var(--ease),
        padding-left var(--dur-2) var(--ease);
}

.dropdown-menu li a:hover {
    padding-left: var(--s-5);
}

@keyframes m-menu-in {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }
}

/* ---------------------------------------------------------------------
   Controls

   Buttons had hover states and no transition, and no pressed state at
   all — on a touch screen there was no confirmation that a tap had
   registered until the next page began to load.
   --------------------------------------------------------------------- */

.btn-primary,
.cta-button,
.client-login-btn,
.nav-links > li > a.client-login-btn,
.float-btn,
.back-link,
.back-button {
    transition:
        background-color var(--dur-2) var(--ease),
        border-color var(--dur-2) var(--ease),
        color var(--dur-2) var(--ease),
        transform var(--dur-1) var(--ease);
}

.btn-primary:active,
.cta-button:active,
.client-login-btn:active,
.float-btn:active {
    transform: translateY(1px);
}

.learn-more,
.doc-download,
.office-location a,
.contact-info a,
.footer-section a,
.social-link {
    transition:
        color var(--dur-2) var(--ease),
        border-color var(--dur-2) var(--ease);
}

.contact-form input,
.contact-form textarea,
.payment-form input,
.payment-form textarea,
.payment-form select {
    transition: border-color var(--dur-2) var(--ease);
}

/* The result of submitting the contact form used to appear in a single
   frame directly above the button, which is easy to miss when you are
   still looking at the field you last typed in. */
.form-status {
    animation: m-status-in var(--dur-4) var(--ease-expo) both;
}

@keyframes m-status-in {
    from {
        opacity: 0;
        transform: translateY(-6px);
    }
}

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

   The rule-separated lists are the substance of these sites — practice
   areas, judgements, public information documents. Each row gets a brass
   tick that wipes down its left edge on hover, set in the container's
   gutter so it does not move the text.

   No transform on the rows themselves: they are reveal targets, and the
   two would fight over the same property.
   --------------------------------------------------------------------- */

.practice-item,
.judgement-item,
.info-doc-card,
.news-card,
.pdf-link {
    position: relative;
}

.practice-item::before,
.judgement-item::before,
.info-doc-card::before,
.pdf-link::before {
    content: '';
    position: absolute;
    left: calc(-1 * var(--s-4));
    top: -1px;
    bottom: -1px;
    width: 2px;
    background: var(--m-metal);
    transform: scaleY(0);
    transform-origin: center top;
    transition: transform var(--dur-2) var(--ease);
}

.practice-item:hover::before,
.judgement-item:hover::before,
.info-doc-card:hover::before,
.pdf-link:hover::before {
    transform: scaleY(1);
}

.practice-item h3,
.judgement-item h4,
.doc-title,
.pdf-title,
.news-title,
.judgement-icon,
.doc-icon,
.practice-index {
    transition: color var(--dur-2) var(--ease);
}

.practice-item:hover h3,
.practice-item:hover .practice-index,
.news-card:hover .news-title {
    color: var(--m-accent);
}

/* The thumbnails sit in a fixed 4:3 frame with overflow hidden, so the
   image can move inside it without disturbing the grid. */
.news-image {
    transition: transform 640ms var(--ease-expo);
}

.news-card:hover .news-image {
    transform: scale(1.04);
}

/* Greyscale until you look at it. The switch was instant. */
.office-map iframe {
    transition: filter var(--dur-4) var(--ease);
}

.category-icon {
    transition: transform var(--dur-2) var(--ease);
}

.category:hover .category-icon {
    transform: translateX(2px);
}

.court-link,
.judgement-item,
.info-doc-card,
.pdf-link {
    transition-property: color, padding-left, background-color;
    transition-duration: var(--dur-2);
    transition-timing-function: var(--ease);
}

/* ---------------------------------------------------------------------
   Mobile menu

   display:none cannot be transitioned, so the panel animates on the frame
   it is drawn and the toggle's three bars fold into a cross. The bars are
   1.5px tall with a 5px gap, which puts 6.5px between the centre of each
   and the centre of the middle one.
   --------------------------------------------------------------------- */

.menu-toggle span {
    transition:
        transform var(--dur-2) var(--ease),
        opacity var(--dur-1) linear;
}

.menu-toggle[aria-expanded='true'] span:nth-child(1) {
    transform: translateY(6.5px) rotate(45deg);
}

.menu-toggle[aria-expanded='true'] span:nth-child(2) {
    opacity: 0;
}

.menu-toggle[aria-expanded='true'] span:nth-child(3) {
    transform: translateY(-6.5px) rotate(-45deg);
}

@media (max-width: 880px) {
    .nav-links.active {
        animation: m-nav-in var(--dur-2) var(--ease) both;
    }

    /* In the stacked panel the links already sit on their own rules; a
       second one wiping in underneath reads as a mistake. */
    .nav-links > li > a::after {
        content: none;
    }

    .dropdown-menu li a:hover {
        padding-left: var(--s-3);
    }

    section[id],
    [id].section {
        scroll-margin-top: 76px;
    }
}

@keyframes m-nav-in {
    from {
        opacity: 0;
        transform: translateY(-6px);
    }
}

/* ---------------------------------------------------------------------
   Disclaimer and floating actions

   The disclaimer is the first thing every visitor sees, on every visit,
   because the Bar Council rules require it. It appeared fully formed in
   the first painted frame.
   --------------------------------------------------------------------- */

.js-motion .disclaimer-overlay {
    animation: m-fade-in var(--dur-2) var(--ease) both;
}

.js-motion .disclaimer-modal,
.js-motion .disclaimer-popup {
    animation: m-modal-in var(--dur-4) var(--ease-expo) both;
}

@keyframes m-fade-in {
    from {
        opacity: 0;
    }
}

@keyframes m-modal-in {
    from {
        opacity: 0;
        transform: translateY(12px);
    }
}

.js-motion .floating-actions {
    animation: m-fade-in var(--dur-4) var(--ease) 400ms both;
}

.float-btn:hover {
    transform: translateY(-2px);
}

/* ---------------------------------------------------------------------
   Reduced motion

   scripts/motion.js returns before it adds .js-motion, so nothing above
   that hides content is ever applied — no split headings, no clipped
   images, no parallax. This is the backstop for the transitions and
   keyframes, which are not gated on the class because they only ever
   move a state the page already reaches.
   --------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 1ms !important;
        animation-delay: 0ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
        transition-delay: 0ms !important;
    }

    .js-motion [data-reveal],
    .js-motion [data-lines] .m-line-i {
        opacity: 1 !important;
        transform: none !important;
    }

    .js-motion [data-unmask] {
        clip-path: none !important;
    }

    .m-parallax {
        transform: none !important;
    }
}
