/*
 * Roote Technologies, the corporate site.
 *
 * The design is a kanga: the printed cotton cloth worn across Tanzania
 * and the coast. A kanga has three parts, and so does every band here.
 *
 *   pindo  the border that runs around the cloth
 *   mji    the central field ("town"), where the design lives
 *   jina   the printed message, always framed, always a saying
 *
 * That last part is why the form fits this company: a kanga is cloth
 * that makes a statement and expects to be read.
 *
 * The rules that follow from it:
 *   - flat, saturated colour fields. No gradients anywhere.
 *   - square corners. Printed cloth has no rounded cards.
 *   - borders instead of shadows. Nothing floats; everything is printed.
 *   - symmetry. Kanga design is centred, so much of this is centred.
 *
 * CORPORATE RESTRAINT (2026-09-20). The first cut of this was too loud
 * and too large for a technology company. The cloth stays; the volume
 * comes down:
 *   - the scale is tight. Every image has a hard max-height, not just an
 *     aspect ratio, because two unbounded images make a page feel amateur.
 *   - the motif is used at the edges of a band, not everywhere at once.
 *   - chalk and paper carry most of the page; indigo, flame and emerald
 *     are punctuation, not the default.
 *   - more whitespace, less ornament per screen.
 *
 * Type is one superfamily at three widths (Archivo, Archivo Black,
 * Archivo Narrow), the way a print shop owns one face and uses it hard.
 *
 * Still a plain stylesheet with no build step: deploys are a zip
 * uploaded to a host with no terminal, and a build that has to run there
 * is a build that eventually does not run.
 */

/* ============================================================== TOKENS */

:root {
    /* The cloth */
    --night: #15120E;
    --chalk: #F7F2E8;
    --chalk-dim: rgba(247, 242, 232, 0.76);
    --chalk-faint: rgba(247, 242, 232, 0.52);
    --paper: #EFE8D8;

    /* The dyes */
    --indigo: #17307E;
    --flame: #CE3B1E;
    --flame-deep: #9E2A11;
    --mustard: #E4A11B;
    --emerald: #0D6B4E;

    /* Ink on cloth */
    --text: #15120E;
    --text-soft: #514738;
    --text-faint: #7A6E5C;
    --rule: rgba(21, 18, 14, 0.22);
    --rule-soft: rgba(21, 18, 14, 0.10);

    --wrap: 1120px;
    --header-h: 60px;
    --pindo-h: 14px;

    --face: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
    --face-display: 'Archivo Black', 'Archivo', system-ui, sans-serif;
    --face-narrow: 'Archivo Narrow', 'Archivo', system-ui, sans-serif;
}

*, *::before, *::after { box-sizing: border-box; }

html {
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--header-h) + var(--pindo-h) + 12px);
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    font-family: var(--face);
    font-size: 15.5px;
    line-height: 1.62;
    color: var(--text-soft);
    background: var(--paper);
    -webkit-font-smoothing: antialiased;
    overflow-x: hidden;
}

img, svg { max-width: 100%; height: auto; display: block; }
a { color: inherit; }

/* ================================================================ TYPE */

h1, h2, h3, h4 { margin: 0 0 0.4em; color: var(--text); }

.display {
    font-family: var(--face-display);
    font-weight: 400;
    text-transform: uppercase;
    /* Archivo Black is a heavy face with a tall cap height. Measured
       at 1.04, the line boxes of a wrapped heading overlapped by 6 to 8
       pixels. 1.16 is the point where uppercase lines clear each other
       and the heading still reads as display type rather than prose. */
    line-height: 1.16;
    letter-spacing: -0.02em;
    text-wrap: balance;
}

h1.display { font-size: clamp(1.75rem, 3.8vw, 2.9rem); line-height: 1.13; }
h2.display { font-size: clamp(1.3rem, 2.4vw, 1.8rem); }
h3.display { font-size: clamp(1rem, 1.5vw, 1.2rem); }

/* A supporting line under a heading. Quieter on purpose. */
.sub {
    font-family: var(--face-narrow);
    font-weight: 600;
    font-size: clamp(.95rem, 1.2vw, 1.05rem);
    line-height: 1.4;
}

.lede { font-size: clamp(.95rem, 1.05vw, 1.02rem); line-height: 1.62; }

/* Metadata and labels, set small and tracked. */
.label {
    font-family: var(--face-narrow);
    font-weight: 700;
    font-size: 11.5px;
    letter-spacing: 0.15em;
    line-height: 1.6;
    text-transform: uppercase;
}

p { margin: 0 0 .9em; }
p:last-child { margin-bottom: 0; }

.muted { color: var(--text-soft); }
.faint { color: var(--text-faint); }
.centre { text-align: center; }

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 22px; }
.wrap-narrow { max-width: 680px; margin: 0 auto; padding: 0 22px; }

.skip-link {
    position: absolute; left: -9999px; top: 0; z-index: 300;
    background: var(--flame); color: var(--chalk);
    padding: 12px 20px; font-family: var(--face-narrow);
    font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em;
    text-decoration: none;
}
.skip-link:focus { left: 0; }

:focus-visible { outline: 3px solid var(--flame); outline-offset: 2px; }

/* =============================================================== PINDO */

/*
 * A border band. It is a mask, not an image, so `color` on the element
 * decides what colour the motif prints in: one SVG serves every band.
 */
.pindo {
    height: var(--pindo-h);
    background-color: currentColor;
    -webkit-mask-image: url('/brand/pindo-belt.svg');
    mask-image: url('/brand/pindo-belt.svg');
    -webkit-mask-repeat: repeat-x;
    mask-repeat: repeat-x;
    -webkit-mask-size: auto 100%;
    mask-size: auto 100%;
    -webkit-mask-position: center;
    mask-position: center;
}

.pindo-wave {
    -webkit-mask-image: url('/brand/pindo-wave.svg');
    mask-image: url('/brand/pindo-wave.svg');
    height: 10px;
}
.pindo-ray {
    -webkit-mask-image: url('/brand/pindo-ray.svg');
    mask-image: url('/brand/pindo-ray.svg');
    height: 11px;
}

/* The flipped copy that closes a band, so the two edges mirror each
   other the way a cloth's hems do. */
.pindo-flip { transform: scaleY(-1); }
.pindo-thin { height: 9px; }

/* ================================================== BANDS (the cloth) */

/*
 * A band is a piece of cloth. When it is bordered it is a `.cloth`,
 * whose children are a pindo, an `.mji` (the field the content sits in)
 * and a closing pindo: the three parts of a kanga, in that order, in
 * normal flow. Nothing is absolutely positioned, because a border that
 * floats over the content eventually lands on top of a heading.
 */
.band { padding: clamp(38px, 4.2vw, 62px) 0; position: relative; }
.band-tight { padding: clamp(22px, 2.6vw, 34px) 0; }

.cloth { position: relative; }
.mji { position: relative; padding: clamp(38px, 4.2vw, 62px) 0; }
.mji-tight { padding: clamp(22px, 2.6vw, 34px) 0; }

.on-paper { background: var(--paper); color: var(--text); }
.on-chalk { background: var(--chalk); color: var(--text); }
.on-night { background: var(--night); color: var(--chalk); }
.on-indigo { background: var(--indigo); color: var(--chalk); }
.on-flame { background: var(--flame); color: var(--chalk); }
.on-emerald { background: var(--emerald); color: var(--chalk); }
.on-mustard { background: var(--mustard); color: var(--night); }

.on-night .muted, .on-indigo .muted, .on-flame .muted, .on-emerald .muted { color: var(--chalk-dim); }
.on-night .faint, .on-indigo .faint, .on-flame .faint, .on-emerald .faint { color: var(--chalk-faint); }
.on-night h1, .on-night h2, .on-night h3,
.on-indigo h1, .on-indigo h2, .on-indigo h3,
.on-flame h1, .on-flame h2, .on-flame h3,
.on-emerald h1, .on-emerald h2, .on-emerald h3 { color: var(--chalk); }
.on-mustard .muted { color: rgba(21, 18, 14, 0.76); }
.on-mustard .faint { color: rgba(21, 18, 14, 0.56); }

/* The motif tiled across a colour field, faintly, so a large flat area
   has cloth texture rather than looking like a div. Used on the hero and
   the closing band only: everywhere would be noise. */
.field::before {
    content: '';
    position: absolute; inset: 0;
    background-color: currentColor;
    opacity: 0.06;
    -webkit-mask-image: url('/brand/mji-field.svg');
    mask-image: url('/brand/mji-field.svg');
    -webkit-mask-size: 88px 88px;
    mask-size: 88px 88px;
    -webkit-mask-repeat: repeat;
    mask-repeat: repeat;
    pointer-events: none;
}
.field > * { position: relative; }

.section-head { max-width: 640px; margin-bottom: clamp(20px, 2.6vw, 32px); }
.section-head .lede { margin-top: 8px; }
.section-head-centre { margin-inline: auto; text-align: center; }

.section-bar {
    display: flex; align-items: flex-end; justify-content: space-between;
    gap: 18px; flex-wrap: wrap;
    margin-bottom: clamp(18px, 2.4vw, 28px);
}

/* ======================================================= SECTION MARK */

/*
 * Replaces the little rounded "eyebrow" pill: a printed tab, index
 * number then section name.
 */
.mark {
    display: inline-flex; align-items: stretch;
    border: 2px solid currentColor;
    margin-bottom: 18px;
}
.mark span {
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 11px;
    letter-spacing: 0.16em; text-transform: uppercase;
    padding: 8px 13px;
    display: flex; align-items: center;
}
.mark .mark-no { background: currentColor; }
.mark .mark-no b { color: var(--paper); font-weight: 700; }
.on-night .mark .mark-no b, .on-indigo .mark .mark-no b,
.on-flame .mark .mark-no b, .on-emerald .mark .mark-no b { color: var(--night); }
.on-mustard .mark .mark-no b { color: var(--mustard); }

/* =========================================================== STATEMENT */

/*
 * The jina: the message panel. Always framed, always short.
 */
.statement {
    border: 3px double currentColor;
    padding: clamp(22px, 2.8vw, 34px);
    max-width: 660px;
    margin-inline: auto;
    text-align: center;
}
.statement-text {
    font-family: var(--face-display);
    text-transform: uppercase;
    font-size: clamp(1.05rem, 1.8vw, 1.4rem);
    line-height: 1.38;
    letter-spacing: -0.01em;
    margin: 0;
    color: inherit;
}
.statement-rule { width: 54px; height: 2px; background: currentColor; margin: 14px auto; opacity: .55; }
.statement-detail {
    font-family: var(--face-narrow);
    font-weight: 500;
    font-size: clamp(.92rem, 1.1vw, 1rem);
    line-height: 1.5;
    margin: 0;
    opacity: .9;
}
.statement-left { text-align: left; margin-inline: 0; }
.statement-left .statement-rule { margin-inline: 0; }

/* ============================================================= BUTTONS */

.btn {
    display: inline-flex; align-items: center; gap: 10px;
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 12.5px;
    letter-spacing: 0.12em; text-transform: uppercase;
    padding: 11px 20px;
    border: 2px solid currentColor;
    background: transparent;
    text-decoration: none; cursor: pointer;
    position: relative; overflow: hidden;
    transition: color .16s linear;
}
/* The fill wipes across the button instead of cross-fading. Print has no
   z-axis, so nothing lifts. */
.btn::before {
    content: '';
    position: absolute; inset: 0;
    background: currentColor;
    transform: scaleX(0); transform-origin: left center;
    transition: transform .26s cubic-bezier(.22, .61, .36, 1);
    z-index: 0;
}
.btn:hover::before { transform: scaleX(1); }
.btn > * { position: relative; z-index: 1; }
.btn:hover span { color: var(--paper); }
.on-night .btn:hover span, .on-indigo .btn:hover span,
.on-flame .btn:hover span, .on-emerald .btn:hover span { color: var(--night); }
.on-mustard .btn:hover span { color: var(--mustard); }

.btn-solid { background: var(--flame); border-color: var(--flame); color: var(--chalk); }
.btn-solid::before { background: var(--flame-deep); }
.btn-solid:hover span { color: var(--chalk); }

.btn-row { display: flex; flex-wrap: wrap; gap: 12px; }
.btn-row-centre { justify-content: center; }

/* A link is text plus an arrow. No icon set, no circles. */
.go {
    display: inline-flex; align-items: baseline; gap: 8px;
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 12px;
    letter-spacing: 0.13em; text-transform: uppercase;
    text-decoration: none;
    border-bottom: 2px solid currentColor;
    /* Enough for a descender to clear the rule. */
    padding-bottom: 7px;
}
.go::after { content: '\2192'; transition: transform .18s ease; }
.go:hover::after { transform: translateX(4px); }
.go-back::after { content: none; }
.go-back::before { content: '\2190'; }

/* ============================================================== HEADER */

/* The selvedge and the header travel together, so the mobile menu can
   hang off a single known height. */
.header-stack { position: sticky; top: 0; z-index: 100; transition: box-shadow .25s ease; }
.header-stack.is-scrolled { box-shadow: 0 6px 0 -4px rgba(21, 18, 14, 0.18); }

/* The selvedge: the printed edge of the cloth, at the very top. */
.selvedge { color: var(--flame); background: var(--night); }
.selvedge .pindo { height: var(--pindo-h); transition: height .3s cubic-bezier(.22,.61,.36,1); }
.header-stack.is-scrolled .selvedge .pindo { height: 7px; }

.site-header {
    background: var(--chalk);
    border-bottom: 2px solid var(--night);
    height: var(--header-h);
    transition: height .3s cubic-bezier(.22,.61,.36,1);
}
.header-stack.is-scrolled .site-header { height: 54px; }
.site-header .wrap { height: 100%; display: flex; align-items: center; gap: 22px; }

/* ---------------------------------------------------------- wordmark */

.wordmark {
    display: inline-flex; align-items: center; gap: 9px;
    text-decoration: none; line-height: 1;
    color: var(--flame);
}
.wordmark-mark { width: 24px; height: 24px; flex-shrink: 0; }
.wordmark-text {
    font-family: var(--face-display);
    text-transform: uppercase;
    letter-spacing: -0.035em;
    font-size: 20px;
    color: var(--text);
}
.on-night .wordmark, .on-indigo .wordmark, .on-flame .wordmark, .on-emerald .wordmark { color: var(--mustard); }
.on-night .wordmark-text, .on-indigo .wordmark-text,
.on-flame .wordmark-text, .on-emerald .wordmark-text { color: var(--chalk); }

.wordmark-sub {
    display: block;
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 9px;
    letter-spacing: 0.3em; text-transform: uppercase;
    color: var(--text-faint);
    margin-top: 3px;
}
.on-night .wordmark-sub { color: var(--chalk-faint); }

.wordmark-lg .wordmark-mark { width: 44px; height: 44px; }
.wordmark-lg .wordmark-text { font-size: 34px; }

/* -------------------------------------------------------------- nav */

.nav { display: flex; align-items: center; margin-left: auto; height: 100%; }
.nav a {
    position: relative;
    display: flex; align-items: center;
    padding: 0 13px;
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 12px;
    letter-spacing: 0.11em; text-transform: uppercase;
    color: var(--text);
    text-decoration: none;
    transition: color .14s linear;
}
/* A printed rule under the current item, drawn on rather than a tinted
   block behind the text. */
.nav a::after {
    content: '';
    position: absolute; left: 13px; right: 13px; bottom: 11px;
    height: 3px; background: var(--flame);
    transform: scaleX(0); transform-origin: left center;
    transition: transform .22s cubic-bezier(.22,.61,.36,1);
}
.nav a:hover::after, .nav a.is-current::after { transform: scaleX(1); }
.nav a.is-current { color: var(--flame-deep); }

.nav-cta {
    background: var(--flame);
    color: var(--chalk) !important;
    margin-left: 12px;
    padding: 0 16px !important;
}
.nav-cta::after { content: none !important; }
.nav-cta:hover { background: var(--flame-deep); }

.nav-toggle {
    display: none; margin-left: auto;
    background: var(--night); color: var(--chalk);
    border: 0; padding: 10px 15px; cursor: pointer;
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 12px;
    letter-spacing: 0.15em; text-transform: uppercase;
}

@media (max-width: 1000px) {
    .nav-toggle { display: block; }
    .nav {
        display: none;
        position: fixed; inset: calc(var(--header-h) + var(--pindo-h)) 0 auto 0;
        flex-direction: column; align-items: stretch; height: auto;
        background: var(--night);
        border-bottom: 5px solid var(--flame);
        padding: 6px 0 12px;
        margin-left: 0;
    }
    .nav.is-open { display: flex; }
    .nav a {
        border-bottom: 1px solid rgba(247, 242, 232, 0.12);
        padding: 13px 22px;
        color: var(--chalk);
        font-size: 13px;
    }
    .nav a::after { left: 22px; right: auto; width: 14px; bottom: 9px; }
    .nav-cta { margin-left: 0; }
}

/* ================================================================ HERO */

.hero { position: relative; padding: clamp(40px, 4.8vw, 68px) 0 clamp(34px, 4vw, 56px); }
.hero .wrap { text-align: center; }
.hero h1 { margin-bottom: 0; }
.hero .hero-sub {
    margin: 16px auto 0; max-width: 58ch;
    font-family: var(--face-narrow);
    font-weight: 500;
    font-size: clamp(.95rem, 1.2vw, 1.06rem);
    line-height: 1.55;
}
.hero .btn-row { margin-top: 26px; }

.page-head { position: relative; padding: clamp(30px, 3.6vw, 48px) 0 clamp(22px, 2.8vw, 34px); }
.page-head .wrap { text-align: center; }
.page-head .lede { max-width: 58ch; margin: 12px auto 0; }

/* ============================================================= LEDGER */

/* The numbers strip: hard dividing rules, no boxes, a printed table. */
.ledger {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    border: 2px solid currentColor;
}
.ledger-cell { padding: 22px 18px; border-left: 2px solid currentColor; text-align: center; }
.ledger-cell:first-child { border-left: 0; }
.ledger-value {
    font-family: var(--face-display);
    text-transform: uppercase;
    font-size: clamp(1.35rem, 2.1vw, 1.75rem);
    line-height: 1;
}
.ledger-label {
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 11.5px;
    letter-spacing: 0.13em; text-transform: uppercase;
    line-height: 1.4;
    margin-top: 10px;
}
.ledger-note { font-size: 12.5px; line-height: 1.45; margin-top: 5px; opacity: .72; }

@media (max-width: 680px) {
    .ledger-cell { border-left: 0; border-top: 2px solid currentColor; }
    .ledger-cell:first-child { border-top: 0; }
}

/* ============================================================= PANELS */

/* Replaces the card: printed on, never floating. */
.panel {
    border: 2px solid var(--rule);
    background: var(--chalk);
    padding: 20px;
    display: flex; flex-direction: column;
    transition: border-color .16s linear, background-color .16s linear;
}
a.panel { text-decoration: none; color: inherit; }
a.panel:hover { border-color: var(--night); background: #FFFDF7; }

.on-night .panel, .on-indigo .panel, .on-flame .panel, .on-emerald .panel {
    background: transparent; border-color: rgba(247, 242, 232, 0.32);
}
.on-night a.panel:hover, .on-indigo a.panel:hover,
.on-flame a.panel:hover, .on-emerald a.panel:hover {
    background: rgba(247, 242, 232, 0.07); border-color: var(--chalk);
}

.panel-foot { margin-top: auto; padding-top: 18px; }

/* A panel whose top edge is a printed rule in an accent colour. */
.panel-tab { border-top-width: 6px; border-top-style: solid; }

.grid { display: grid; gap: 14px; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
.grid-4 { grid-template-columns: repeat(auto-fit, minmax(175px, 1fr)); }

.split {
    display: grid; gap: clamp(20px, 2.8vw, 40px); align-items: start;
    grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
}
/* A narrow sidebar next to a wide column. Stacks below the breakpoint;
   a fixed inline width here would simply overflow a phone. */
.split-aside { grid-template-columns: minmax(0, 230px) minmax(0, 1fr); }
@media (max-width: 720px) { .split-aside { grid-template-columns: 1fr; } }

/* ============================================================ PRODUCT */

.product-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.product-glyph {
    width: 38px; height: 38px; flex-shrink: 0;
    display: grid; place-items: center;
    font-family: var(--face-display); font-size: 17px;
    text-transform: uppercase; color: var(--chalk);
    background: var(--product-accent, var(--flame));
}
.product-logo { width: 38px; height: 38px; object-fit: contain; flex-shrink: 0; }
.product-name {
    font-family: var(--face-display);
    text-transform: uppercase;
    font-size: 1.15rem; line-height: 1.22; letter-spacing: -0.02em;
    color: var(--text);
}
.product-cat {
    display: block;
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 10.5px;
    letter-spacing: 0.14em; text-transform: uppercase;
    opacity: .66; margin-top: 4px;
}
.on-night .product-name, .on-indigo .product-name { color: var(--chalk); }

/* The wide product block. The image is capped hard: it illustrates the
   product, it is not the point of the page. */
.product-sheet {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, .8fr);
    border: 2px solid var(--rule);
    background: var(--chalk);
    transition: border-color .18s linear;
}
.product-sheet:hover { border-color: var(--night); }
.product-sheet-body { padding: clamp(18px, 2.4vw, 28px); }
.product-sheet-art {
    background: var(--product-accent, var(--flame));
    border-left: 2px solid var(--rule);
    min-height: 180px; max-height: 260px;
    overflow: hidden;
}
.product-sheet-art img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 880px) {
    .product-sheet { grid-template-columns: 1fr; }
    .product-sheet-art {
        order: -1; border-left: 0; border-bottom: 2px solid var(--rule);
        min-height: 0; max-height: none; height: 170px;
    }
}

/* ============================================================== STAMP */

/* Status and category: a printed stamp rather than a pill. */
.stamp {
    display: inline-flex; align-items: center; gap: 6px;
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 10.5px;
    letter-spacing: 0.15em; text-transform: uppercase;
    padding: 6px 11px;
    border: 2px solid currentColor;
}
.stamp-live { color: var(--emerald); }
.stamp-beta { color: var(--flame-deep); }
.on-night .stamp, .on-indigo .stamp, .on-flame .stamp, .on-emerald .stamp { color: var(--chalk); }
.stamp .dot { width: 6px; height: 6px; background: currentColor; }

/* =============================================================== NEWS */

.news-media {
    /* Height, not aspect-ratio + max-height: the pair sizes the whole
       box, so the cap shrank the width and the image stopped filling
       the card. A fixed height also keeps every card's image aligned. */
    height: 150px;
    overflow: hidden; background: var(--indigo);
    margin: -20px -20px 16px;
}
.news-media img { width: 100%; height: 100%; object-fit: cover; }
.news-meta {
    display: flex; flex-wrap: wrap; align-items: center; gap: 9px;
    line-height: 1.6;
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 10.5px;
    letter-spacing: 0.12em; text-transform: uppercase;
    margin-bottom: 10px;
}
.news-title {
    font-family: var(--face-display);
    text-transform: uppercase;
    font-size: 1.02rem; line-height: 1.38; letter-spacing: -0.015em;
    color: var(--text);
    margin-bottom: 9px;
}

.lead-story { display: grid; grid-template-columns: 1fr 1fr; padding: 0; }
.lead-story-art { background: var(--indigo); min-height: 180px; max-height: 250px; overflow: hidden; }
.lead-story-art img { width: 100%; height: 100%; object-fit: cover; }
.lead-story-body { padding: clamp(18px, 2.4vw, 28px); display: flex; flex-direction: column; justify-content: center; }
@media (max-width: 860px) {
    .lead-story { grid-template-columns: 1fr; }
    .lead-story-art { min-height: 0; max-height: none; height: 170px; }
}

/* ============================================================ ARTICLE */

.prose { font-size: 16px; line-height: 1.7; }
.prose h2 {
    font-family: var(--face-display);
    text-transform: uppercase;
    font-size: clamp(1.2rem, 1.9vw, 1.5rem);
    line-height: 1.1; letter-spacing: -0.015em;
    margin: 1.7em 0 .45em;
}
.prose h3 {
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 1.1rem;
    text-transform: uppercase; letter-spacing: 0.04em;
    margin: 1.5em 0 .35em;
}
.prose ul, .prose ol { padding-left: 1.15em; margin: 0 0 1em; }
.prose li { margin-bottom: .4em; }
.prose a { color: var(--flame-deep); text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 2px; }
.prose blockquote {
    margin: 1.5em 0; padding: 20px 24px;
    border-left: 6px solid var(--flame);
    background: var(--chalk);
    font-family: var(--face-narrow);
    font-weight: 500; font-size: 1.05em;
}
.prose hr { border: 0; border-top: 2px solid var(--rule); margin: 1.9em 0; }
.prose img { margin: 1.4em 0; }

.article-art {
    height: clamp(170px, 26vw, 300px);
    overflow: hidden; background: var(--indigo);
    border: 2px solid var(--rule);
}
.article-art img { width: 100%; height: 100%; object-fit: cover; }

/* ======================================================= PHOTO PLATE */

/*
 * A photograph printed as part of the cloth rather than dropped on top
 * of it: bordered like everything else, and tinted with one of the dyes
 * so a stock photograph stops looking like stock and starts looking
 * like a print.
 *
 * Deliberately short. A wide, shallow band reads as a detail on the page
 * instead of taking the page over, and the max-height is what actually
 * enforces that: an aspect ratio alone still grows with the column.
 */
.plate {
    position: relative;
    overflow: hidden;
    background: var(--indigo);
    border: 2px solid var(--rule);
}
.plate img { width: 100%; height: 100%; object-fit: cover; display: block; }

.plate-tint::after {
    content: '';
    position: absolute; inset: 0;
    background: var(--plate-tint, var(--indigo));
    mix-blend-mode: multiply;
    opacity: .45;
    pointer-events: none;
}

/*
 * A fixed height rather than an aspect ratio with a cap: aspect-ratio
 * sizes the whole box, so max-height also shrank the width and the band
 * stopped filling its column. Height alone keeps it full width and lets
 * object-fit crop the photograph instead.
 */
.plate-band { height: clamp(130px, 17vw, 190px); width: 100%; }

/* ============================================================= PEOPLE */

.person-photo {
    aspect-ratio: 4 / 5; max-width: 150px;
    overflow: hidden;
    background: var(--indigo); color: var(--chalk);
    display: grid; place-items: center;
    border: 2px solid var(--rule);
    margin-bottom: 12px;
}
.person-photo img { width: 100%; height: 100%; object-fit: cover; }
.person-initials { font-family: var(--face-display); font-size: 1.9rem; text-transform: uppercase; color: var(--mustard); }
.person-name {
    font-family: var(--face-display);
    text-transform: uppercase;
    font-size: 1rem; line-height: 1.25; letter-spacing: -0.015em;
    color: var(--text);
}
.person-role {
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 10.5px;
    letter-spacing: 0.14em; text-transform: uppercase;
    color: var(--flame-deep); margin: 5px 0 6px;
}
.on-night .person-name, .on-indigo .person-name { color: var(--chalk); }
.on-night .person-role, .on-indigo .person-role { color: var(--mustard); }
.person-links { display: flex; gap: 12px; margin-top: 10px; }
.person-links a { color: var(--text-faint); }
.person-links a:hover { color: var(--flame-deep); }
.person-links svg { width: 16px; height: 16px; }

/* ============================================================== ROLES */

.roles { border-top: 2px solid var(--rule); }
.role {
    display: flex; flex-wrap: wrap; align-items: center; gap: 14px;
    padding: 19px 8px;
    border-bottom: 2px solid var(--rule);
    text-decoration: none; color: inherit;
    transition: background-color .14s linear, padding-left .16s ease;
}
.role:hover { background: var(--chalk); padding-left: 14px; }
.role-title {
    font-family: var(--face-display);
    text-transform: uppercase;
    font-size: 1.02rem; line-height: 1.26; letter-spacing: -0.015em;
    color: var(--text);
}
.role-meta {
    font-family: var(--face-narrow);
    font-weight: 600; font-size: 11.5px;
    letter-spacing: 0.09em; text-transform: uppercase;
    line-height: 1.5;
    color: var(--text-faint); margin-top: 7px;
}
.role-go { margin-left: auto; color: var(--flame-deep); font-size: 19px; }

.empty { border: 3px double var(--rule); padding: 38px 24px; text-align: center; }

/* =============================================================== LISTS */

.ticks { list-style: none; margin: 0; padding: 0; }
.ticks li { position: relative; padding-left: 24px; margin-bottom: 10px; }
.ticks li::before {
    content: ''; position: absolute; left: 0; top: .58em;
    width: 8px; height: 8px; background: var(--flame);
}
.on-night .ticks li::before, .on-indigo .ticks li::before { background: var(--mustard); }

/* Numbered promises: a printed index, not a card grid. */
.index-list { list-style: none; margin: 0; padding: 0; counter-reset: n; border-top: 2px solid currentColor; }
.index-list li {
    counter-increment: n;
    display: grid; grid-template-columns: 58px 1fr; gap: 18px;
    padding: 20px 0;
    border-bottom: 2px solid currentColor;
}
.index-list li::before {
    content: counter(n, decimal-leading-zero);
    font-family: var(--face-display);
    font-size: 1.4rem; line-height: 1;
    opacity: .3;
}
.index-list h4 {
    font-family: var(--face-narrow);
    font-weight: 700; font-size: .95rem;
    text-transform: uppercase; letter-spacing: 0.07em;
    margin: 0 0 4px;
}
.index-list p { margin: 0; font-size: 14.5px; }
@media (max-width: 620px) { .index-list li { grid-template-columns: 1fr; gap: 4px; } }

/* =============================================================== FORM */

.form-grid { display: grid; gap: 15px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.field { display: flex; flex-direction: column; gap: 6px; }
.field-full { grid-column: 1 / -1; }
.field label {
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 11.5px;
    letter-spacing: 0.13em; text-transform: uppercase;
}
.field .hint { font-weight: 500; opacity: .6; letter-spacing: .07em; }

.input, .textarea, .select {
    font-family: var(--face); font-size: 15.5px; color: var(--text);
    background: var(--chalk);
    border: 2px solid var(--rule);
    padding: 11px 13px; width: 100%;
    transition: border-color .14s linear;
}
.input:focus, .textarea:focus, .select:focus { outline: none; border-color: var(--flame); }
.textarea { resize: vertical; min-height: 130px; }
.select {
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3 6l5 5 5-5z' fill='%2315120E'/%3E%3C/svg%3E");
    background-repeat: no-repeat; background-position: right 13px center; background-size: 14px;
    padding-right: 38px;
}
.field-error {
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 11.5px;
    letter-spacing: 0.09em; text-transform: uppercase;
    color: var(--flame-deep);
}
.input.has-error, .textarea.has-error, .select.has-error { border-color: var(--flame); }

.notice { border: 3px double var(--emerald); color: var(--emerald); padding: 16px 18px; margin-bottom: 22px; }
.notice strong { font-family: var(--face-narrow); text-transform: uppercase; letter-spacing: 0.07em; }

/* Hidden from people, not from a bot that fills every field. */
.trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ============================================================= FOOTER */

.site-footer { background: var(--night); color: var(--chalk-dim); }
.footer-main { padding: clamp(34px, 4vw, 54px) 0 24px; }
.footer-top {
    display: grid;
    grid-template-columns: minmax(200px, 1.2fr) repeat(auto-fit, minmax(125px, 1fr));
    gap: 28px 22px;
}
.footer-brand p { margin-top: 12px; max-width: 30ch; color: var(--chalk-faint); font-size: 13.5px; }

.footer-col h4 {
    font-family: var(--face-narrow);
    font-weight: 700; font-size: 10.5px;
    letter-spacing: 0.18em; text-transform: uppercase;
    color: var(--mustard);
    margin: 0 0 14px; padding-bottom: 11px;
    border-bottom: 2px solid rgba(247, 242, 232, 0.16);
}
.footer-col ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.footer-col a { color: var(--chalk-dim); text-decoration: none; font-size: 13.5px; }
.footer-col a:hover { color: var(--chalk); text-decoration: underline; text-underline-offset: 3px; }
.footer-col li { color: var(--chalk-faint); font-size: 13.5px; }

.footer-socials { display: flex; gap: 14px; margin-top: 14px; }
.footer-socials a { color: var(--chalk-faint); }
.footer-socials a:hover { color: var(--mustard); }
.footer-socials svg { width: 17px; height: 17px; }

.footer-bottom {
    margin-top: 32px; padding-top: 22px;
    border-top: 2px solid rgba(247, 242, 232, 0.16);
    display: flex; flex-wrap: wrap; gap: 8px 20px; align-items: center;
    font-family: var(--face-narrow);
    font-weight: 600; font-size: 11.5px;
    letter-spacing: 0.07em; text-transform: uppercase;
    line-height: 1.7;
    color: var(--chalk-faint);
}
.footer-bottom a { color: var(--chalk-faint); text-decoration: none; }
.footer-bottom a:hover { color: var(--chalk); }
.footer-bottom .spacer { margin-left: auto; }

/* ============================================================= MOTION */

/*
 * Ink onto cloth: things wipe and settle. Nothing slides in from
 * off-screen, nothing bounces, nothing floats on a shadow.
 *
 * Gated on `.js-motion`, which site.js adds to <html> only after it has
 * confirmed the visitor has not asked for reduced motion. Without
 * JavaScript the class never lands, nothing is hidden, and the page
 * reads exactly as served.
 */
.js-motion [data-reveal] {
    opacity: 0; transform: translateY(12px);
    transition:
        opacity .5s cubic-bezier(.22, .61, .36, 1) var(--reveal-delay, 0ms),
        transform .5s cubic-bezier(.22, .61, .36, 1) var(--reveal-delay, 0ms),
        clip-path .7s cubic-bezier(.22, .61, .36, 1) var(--reveal-delay, 0ms);
}
.js-motion [data-reveal].is-in { opacity: 1; transform: none; }

/* A heading prints: the ink is rolled on from the left. */
.js-motion [data-reveal='wipe'] { opacity: 1; transform: none; clip-path: inset(0 100% 0 0); }
.js-motion [data-reveal='wipe'].is-in { clip-path: inset(0 0 0 0); }

/* An image settles into focus rather than sliding. */
.js-motion [data-reveal='plate'] {
    opacity: 0; transform: scale(1.03); filter: saturate(.5);
    transition:
        opacity .7s ease var(--reveal-delay, 0ms),
        transform .9s cubic-bezier(.22, .61, .36, 1) var(--reveal-delay, 0ms),
        filter .9s ease var(--reveal-delay, 0ms);
}
.js-motion [data-reveal='plate'].is-in { opacity: 1; transform: none; filter: none; }

@keyframes print-in { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes roll-in { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }

.js-motion .hero .mark { animation: print-in .6s cubic-bezier(.22,.61,.36,1) both; }
.js-motion .hero h1 { animation: roll-in .9s cubic-bezier(.22,.61,.36,1) .1s both; }
.js-motion .hero .hero-sub { animation: print-in .6s cubic-bezier(.22,.61,.36,1) .42s both; }
.js-motion .hero .btn-row { animation: print-in .6s cubic-bezier(.22,.61,.36,1) .54s both; }

/* The cloth breathes: the border motif drifts, the way printed cloth
   moves. Slow enough to be felt rather than watched. */
@keyframes pindo-drift {
    from { -webkit-mask-position: 0 center; mask-position: 0 center; }
    to { -webkit-mask-position: 64px center; mask-position: 64px center; }
}
.js-motion .cloth > .pindo {
    animation: roll-in 1s cubic-bezier(.22,.61,.36,1) both, pindo-drift 11s linear infinite;
}
.js-motion .pindo-flip { animation-direction: normal, reverse; }

.news-media img, .lead-story-art img, .product-sheet-art img {
    transition: transform .8s cubic-bezier(.22, .61, .36, 1);
}
a.panel:hover .news-media img, .product-sheet:hover .product-sheet-art img { transform: scale(1.04); }
a.panel:active { transform: scale(.995); }

@keyframes signal { 0%, 100% { opacity: 1; } 50% { opacity: .3; } }
.js-motion .stamp-live .dot { animation: signal 2.4s ease-in-out infinite; }

/* ========================================================== REFINEMENT */

/*
 * Detail work. Everything here is in the kanga's own vocabulary: printed
 * marks, rules and inversions. Nothing lifts, glows or gradients.
 */

/* A panel's accent rule grows when you point at it, the way a printed
   tab would be inked heavier. */
.panel-tab { transition: border-top-width .18s ease, border-color .16s linear, background-color .16s linear; }
a.panel-tab:hover { border-top-width: 9px; }

/* The index tab inverts on hover, like a stamp pressed down. */
a:hover > .mark, a:focus-visible > .mark { background: currentColor; }
a:hover > .mark span, a:focus-visible > .mark span { color: var(--paper); }
a:hover > .mark .mark-no { background: var(--paper); }
a:hover > .mark .mark-no b { color: var(--text); }

/* A quiet wave rule under a section heading, so a heading and the text
   under it are separated by something that belongs to the cloth. */
.section-head::after {
    content: '';
    display: block;
    width: 58px; height: 8px;
    margin-top: 16px;
    background-color: var(--flame);
    -webkit-mask-image: url('/brand/pindo-wave.svg');
    mask-image: url('/brand/pindo-wave.svg');
    -webkit-mask-repeat: repeat-x; mask-repeat: repeat-x;
    -webkit-mask-size: auto 100%; mask-size: auto 100%;
}
.section-head-centre::after { margin-inline: auto; }
.on-night .section-head::after, .on-indigo .section-head::after,
.on-flame .section-head::after, .on-emerald .section-head::after { background-color: var(--mustard); }

/* The ledger figure counts up, so give the number a fixed tabular width
   and it will not jiggle the layout while it runs. */
.ledger-value { font-variant-numeric: tabular-nums; }

/* The person photo prints its subject in from behind the indigo. */
.person-photo { transition: border-color .18s linear; }
a:hover .person-photo { border-color: var(--night); }
a:hover .person-photo img { transform: scale(1.03); }
.person-photo img { transition: transform .7s cubic-bezier(.22,.61,.36,1); }

/* A role row draws its own rule in as you arrive at it. */
.role { position: relative; }
.role::after {
    content: '';
    position: absolute; left: 0; bottom: -2px; height: 2px; width: 100%;
    background: var(--flame);
    transform: scaleX(0); transform-origin: left center;
    transition: transform .3s cubic-bezier(.22,.61,.36,1);
}
.role:hover::after { transform: scaleX(1); }

/* Links inside running text underline on the cloth's own terms. */
.prose a { text-decoration-thickness: 2px; text-underline-offset: 4px; }

/* The wordmark's mark turns with the page, very slightly, on hover: a
   printed block being set straight. */
.wordmark-mark { transition: transform .35s cubic-bezier(.22,.61,.36,1); }
a:hover > .wordmark .wordmark-mark { transform: rotate(-8deg); }

@media (prefers-reduced-motion: reduce) {
    a.panel-tab:hover { border-top-width: 6px; }
    a:hover > .wordmark .wordmark-mark { transform: none; }
    .role::after { display: none; }
}

/* ========================================================== UTILITIES */

.stack > * + * { margin-top: 16px; }
.stack-sm > * + * { margin-top: 8px; }

@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }
    .role:hover { padding-left: 6px; }
}

/* ===================================================== CORPORATE PASS */

/*
 * 2026-09-24. Same cloth, quieter print: the brief was "keep the kanga,
 * make it read as corporate as the Roove product". So nothing here changes
 * the palette, the pindo, the square corners, the typeface or the layout.
 * It changes volume, the way a firm's letterhead differs from its banner:
 *
 *   - Capitals are for the cloth's own voice only: the page title (h1),
 *     the jina (statement), labels and buttons. Section headings, card
 *     titles and names read in sentence case, which is how every serious
 *     institution sets them and is easier to scan.
 *   - Rules go from 2px to 1px on panels, the ledger and inputs. Heavy
 *     rules stay where they are the motif: the section mark and stamps.
 *   - The border motif rolls on once and then holds still. A pattern that
 *     drifts forever reads as decoration; one that stays reads as print.
 *   - Body text is a touch larger and darker, so long copy is comfortable.
 */

body { font-size: 16px; color: #3F372B; }
.lede { color: #3F372B; }

/* Section headings: sentence case, heavy but not shouting. */
h2.display, h3.display {
    font-family: var(--face);
    font-weight: 700;
    text-transform: none;
    letter-spacing: -0.022em;
    line-height: 1.22;
}
h2.display { font-size: clamp(1.4rem, 2.3vw, 1.85rem); }
h3.display { font-size: clamp(1.05rem, 1.5vw, 1.2rem); }

/* Titles inside panels and lists. */
.product-name, .news-title, .person-name, .role-title, .prose h2 {
    font-family: var(--face);
    font-weight: 700;
    text-transform: none;
    letter-spacing: -0.015em;
}
.product-name { font-size: 1.12rem; }
.news-title { font-size: 1.06rem; line-height: 1.35; }
.person-name { font-size: 1.05rem; }
.role-title { font-size: 1.05rem; }
.prose h2 { font-size: clamp(1.25rem, 1.9vw, 1.5rem); line-height: 1.25; }
.prose h3 { text-transform: none; letter-spacing: -0.01em; font-family: var(--face); }
.index-list h4 { text-transform: none; letter-spacing: -0.005em; font-family: var(--face); font-size: 1rem; }

/* Labels stay in capitals, with less tracking, so they read as metadata
   rather than as a second set of headings. */
.label, .ledger-label, .news-meta, .person-role, .product-cat, .role-meta, .field label, .footer-col h4 {
    letter-spacing: 0.09em;
}
.nav a { letter-spacing: 0.07em; }
.btn { letter-spacing: 0.08em; }

/* Finer rules. */
.panel, .product-sheet, .plate, .article-art, .person-photo { border-width: 1px; }
.product-sheet-art { border-left-width: 1px; }
.ledger, .ledger-cell { border-width: 1px; }
.ledger-cell:first-child { border-left-width: 0; }
.input, .textarea, .select { border-width: 1px; }
.roles, .role { border-width: 1px; }
.index-list { border-top-width: 1px; }
.index-list li { border-bottom-width: 1px; }
.site-header { border-bottom-width: 1px; }
.empty, .statement { border-width: 3px; }
@media (max-width: 1000px) {
    .product-sheet-art { border-bottom-width: 1px; }
}
@media (max-width: 680px) {
    .ledger-cell { border-top-width: 1px; }
    .ledger-cell:first-child { border-top-width: 0; }
}

/* A panel on hover: a firmer rule, no change of paper. */
a.panel:hover { background: var(--chalk); }

/* The motif rolls on once, then holds. */
.js-motion .cloth > .pindo { animation: roll-in 1s cubic-bezier(.22,.61,.36,1) both; }
.js-motion .stamp-live .dot { animation: none; }

/* The ledger's small print was too faint to read. */
.ledger-note { opacity: .85; }

/* Figures in the ledger: the dye colour and weight stay, the capitals go,
   so "Dar es Salaam" reads as a place rather than a slogan. */
.ledger-value { text-transform: none; letter-spacing: -0.02em; }
