/* ============================================================================
   ReturnKoto? UI polish layer
   Version 3, 20 Aug 2026

   Additive only. Loads AFTER each page's inline <style> block and overrides it.
   Nothing here changes markup, copy, data or behaviour. Remove the one <link>
   tag on a page and that page returns exactly to its previous appearance.

   Design intent:
     1. Give desktop a real layout instead of a 760px mobile column.
     2. Give surfaces depth, so cards read as objects rather than outlines.
     3. Make the numbers the loudest thing on every screen.
     4. Keep every change safe at 390px, AA contrast, and 44px tap targets.

   House rules honoured: no em dashes, no en dashes, mobile verified first,
   all motion behind prefers-reduced-motion.
   ========================================================================== */


/* Token fallbacks, and why they are here.

   The site runs two token vocabularies. index.html and the fund pages declare
   --border and --text; the stocks, ratings and versus shell declares --line and
   --ink instead. This stylesheet loads on both, so a bare var(--border) was
   invalid on stocks.html, ratings.html and all 90 versus pages, and every
   declaration using it was silently dropped. Borders and text colours simply
   were not applied there.

   The chain resolves to whichever name the page actually defines, and both are
   theme aware with matching dark values (#2B3648 and #E6EAF2), so light and
   dark are both correct. The hex is a last resort that should never be reached.

   Do not replace these with a :root alias. Declaring --border: var(--line) here
   would override the real --border on index.html, because this file loads last. */

/* ---------------------------------------------------------------------------
   1. TOKENS
   New tokens only. The existing --green, --text, --card and friends are left
   untouched so nothing that already reads them changes meaning.
   ------------------------------------------------------------------------ */

:root{
  /* radius scale */
  --r-sm:9px;
  --r-md:14px;
  --r-lg:18px;
  --r-xl:24px;
  --r-pill:999px;

  /* elevation, tinted rather than pure black so it sits on the green brand */
  --el-1:0 1px 2px rgba(16,32,24,.05), 0 1px 3px rgba(16,32,24,.05);
  --el-2:0 2px 4px rgba(16,32,24,.05), 0 8px 20px rgba(16,32,24,.07);
  --el-3:0 4px 8px rgba(16,32,24,.06), 0 18px 40px rgba(16,32,24,.10);
  --el-green:0 10px 30px rgba(31,158,87,.16);

  /* top edge highlight, the thing that makes a card look lit */
  --edge:inset 0 1px 0 rgba(255,255,255,.9);

  /* surface wash applied over --card */
  --wash:linear-gradient(180deg, rgba(31,158,87,.030), rgba(31,158,87,0) 120px);

  /* accents beyond the single green */
  --accent-ink:#0F3D28;
  --accent-2:#0EA5E9;
  --accent-3:#6366F1;
  --accent-4:#D97706;

  /* ambient glow behind the hero, near invisible in light mode */
  --aura-a:rgba(46,204,113,.10);
  --aura-b:rgba(14,165,233,.06);

  /* layout */
  --measure:64ch;
  --wrap-wide:1080px;
  --wrap-xwide:1180px;
}

[data-theme="dark"]{
  --el-1:0 1px 2px rgba(0,0,0,.40), 0 1px 3px rgba(0,0,0,.35);
  --el-2:0 2px 6px rgba(0,0,0,.45), 0 10px 26px rgba(0,0,0,.45);
  --el-3:0 6px 14px rgba(0,0,0,.50), 0 24px 56px rgba(0,0,0,.55);
  --el-green:0 12px 36px rgba(61,217,138,.18);
  --edge:inset 0 1px 0 rgba(255,255,255,.055);
  --wash:linear-gradient(180deg, rgba(255,255,255,.028), rgba(255,255,255,0) 140px);
  --accent-ink:#CFEFDD;
  --accent-2:#38BDF8;
  --accent-3:#818CF8;
  --accent-4:#F0B24A;
  --aura-a:rgba(46,204,113,.16);
  --aura-b:rgba(56,189,248,.09);
}


/* ---------------------------------------------------------------------------
   2. FOUNDATIONS
   ------------------------------------------------------------------------ */

/* Every figure on the site should line up in columns. */
.hs-main,.hs-sub,.hs-pct,.hs-ann,.hs-gain,
.cbar-num,.cbar-dur,.ba-link,.typehead-n,
.fund-n,.st-u,.asof,.rate input,.rateval,
table td,table th{
  font-variant-numeric:tabular-nums;
  font-feature-settings:"tnum" 1;
}

/* Long prose lines are the quickest way to look unconsidered on a wide screen. */
header p,
.hl-note,
.bcard p,
.browseall p,
.typehead + p,
.sub, .subtle{
  max-width:var(--measure);
}

/* One focus ring for the whole site, visible on both themes. */
a:focus-visible,
button:focus-visible,
select:focus-visible,
input:focus-visible,
summary:focus-visible,
[tabindex]:focus-visible{
  outline:2px solid var(--green);
  outline-offset:2px;
  border-radius:6px;
}

/* Headings sit tighter as they get bigger. */
h1{letter-spacing:-.028em}
h2{letter-spacing:-.02em}

/* The all caps micro labels were low contrast and too tightly tracked. */
label.fld,
.fld,
.rateshead,
.ba-title{
  letter-spacing:.07em;
}
label.fld,.fld{
  font-size:11.5px;
  color:#4A5568;
}
[data-theme="dark"] label.fld,
[data-theme="dark"] .fld{color:#A9B6C9}

/* Selection picks up the brand instead of the browser default. */
::selection{background:rgba(46,204,113,.28)}


/* ---------------------------------------------------------------------------
   3. SURFACES
   Panels become objects: a wash, a lit top edge, a tinted shadow.
   ------------------------------------------------------------------------ */

.panel,
.bcard,
.ba-link,
.qbar{
  border-radius:var(--r-lg);
  background-image:var(--wash);
  box-shadow:var(--el-2), var(--edge);
  transition:box-shadow .18s ease, border-color .18s ease, transform .18s ease;
}

[data-theme="dark"] .panel,
[data-theme="dark"] .bcard,
[data-theme="dark"] .ba-link{
  border-color:#2F3B4F;
}

/* Interactive cards lift. Static panels do not, so the difference means something. */
.ba-link:hover{
  transform:translateY(-2px);
  box-shadow:var(--el-3), var(--edge);
  border-color:var(--green);
}

/* The chart panels are surfaces for data, so give the plot area its own ground. */
.chartpanel{
  border-radius:var(--r-lg);
  padding:20px;
}
@media(max-width:560px){
  .chartpanel{padding:15px 13px}
}


/* ---------------------------------------------------------------------------
   4. NAVIGATION
   ------------------------------------------------------------------------ */

.rk-nav{
  padding:14px 22px;
  border-bottom:1px solid rgba(16,32,24,.07);
  background:rgba(255,255,255,.80);
  backdrop-filter:blur(14px) saturate(1.5);
  -webkit-backdrop-filter:blur(14px) saturate(1.5);
}
[data-theme="dark"] .rk-nav{
  background:rgba(14,20,31,.78);
  border-bottom:1px solid rgba(255,255,255,.07);
}

.rk-links{gap:6px}
.rk-links a{
  padding:9px 11px;
  border-radius:var(--r-sm);
  color:#33463C;
  transition:color .14s, background .14s;
}
[data-theme="dark"] .rk-links a{color:#B9C6D6}
.rk-links a:hover{
  background:rgba(46,204,113,.10);
  color:var(--green-dark);
}
[data-theme="dark"] .rk-links a:hover{color:#5FE3A2}

.themetog{
  min-width:40px;min-height:40px;
  border-radius:var(--r-pill);
  display:inline-flex;align-items:center;justify-content:center;
  transition:background .14s, transform .2s;
}
.themetog:hover{background:rgba(46,204,113,.12);transform:rotate(-12deg)}

.rk-logo svg{
  border-radius:8px;
  box-shadow:0 2px 8px rgba(31,158,87,.30);
}

/* Current page marker. This lived in each page's own inline stylesheet and had
   drifted: index.html set a colour with no underline at all, so Ratings and
   Stocks showed no active state while Funds and Compare did. Defining it here,
   in the layer that loads last on every page, makes it identical everywhere.
   The underline is a pseudo-element so it can also animate on hover, but its
   resting geometry is declared outside the motion block: the active state must
   be visible even for a reader who has asked for reduced motion. */
.rk-links a{position:relative}
.rk-links a::after{
  content:"";
  position:absolute;
  left:50%;right:50%;bottom:5px;
  height:2px;
  border-radius:2px;
  background:var(--green);
}
.rk-links a:hover::after,
.rk-links a.active::after,
.rk-links a[aria-current="page"]::after{
  left:11px;right:11px;
}
.rk-links a.active,
.rk-links a[aria-current="page"]{
  color:var(--green-dark);
  font-weight:700;
}
[data-theme="dark"] .rk-links a.active,
[data-theme="dark"] .rk-links a[aria-current="page"]{color:#3DD98A}

/* Nav was cramped at 390px. Give every item a 44px tap target without letting
   the row overflow: the logo may shrink, the links own the remaining space. */
/* The bar keeps the two destinations people actually reach for; the rest live
   in the burger, which still lists all of them.

   The collapse happens at 860px, not at the 560px phone breakpoint. With
   "Most-held Stocks" in it the full six item row measures about 773px, so once
   the logo and the theme and menu buttons are added it overflows anywhere below
   roughly 800px. Collapsing early is better than a row that wraps or clips. */
@media(max-width:860px){
  .rk-nav .rk-links{
    display:flex;
    gap:0;
    flex:0 0 auto;
    min-width:0;
  }
  .rk-nav .rk-links a{display:none}
  .rk-nav .rk-links a[data-nav="funds"],
  .rk-nav .rk-links a[data-nav="compare"]{
    display:flex;
    align-items:center;
    padding:10px 9px;
    font-size:13.5px;
    min-height:44px;
  }
}

/* Phone sizing, separate from the collapse above. */
@media(max-width:560px){
  .rk-nav{padding:8px 8px;gap:4px}
  .rk-logo{min-width:0;flex:0 1 auto;overflow:hidden}
  .rk-nav .rk-links a[data-nav="funds"],
  .rk-nav .rk-links a[data-nav="compare"]{padding:10px 7px;font-size:12.5px}
  .themetog{min-width:40px;min-height:44px}
}
@media(max-width:400px){
  .rk-nav .rk-links a[data-nav="funds"],
  .rk-nav .rk-links a[data-nav="compare"]{padding:10px 5px;font-size:11.5px}
  .themetog{min-width:34px}
  .rk-logo{font-size:12px}
}


/* ---------------------------------------------------------------------------
   5. THE FOLD
   On desktop this becomes a proper hero split: the promise on the left,
   the calculator on the right, both vertically centred. No markup change,
   the grid is applied to .rk-fold and its two real children.
   ------------------------------------------------------------------------ */

/* Ambient light behind the hero. Sits under everything, ignores pointer events. */
.rk-fold{position:relative}
/* The aura must never bleed sideways. An earlier version used
   inset:-14% -30% auto -30%, which extended 337px past each edge at a 1180px
   wrap and gave the whole page 169px of horizontal scroll. Pseudo-elements do
   not appear in a DOM overflow scan, so it hid well. The gradient centres now
   sit near the edges with large radii instead, which reads the same without
   any box extending past the container. */
.rk-fold::before{
  content:"";
  position:absolute;
  inset:-30px 0 auto 0;
  height:520px;
  pointer-events:none;
  z-index:0;
  background:
    radial-gradient(58% 68% at 6% 26%, var(--aura-a), transparent 72%),
    radial-gradient(52% 62% at 96% 12%, var(--aura-b), transparent 74%);
  filter:blur(12px);
}
/* Only the two real children get lifted above the aura. The screen reader
   heading must keep its own position:absolute or it becomes a grid track. */
.rk-fold > header,
.rk-fold > .panel{position:relative;z-index:1}

header h1{
  font-size:clamp(27px, 5.4vw, 46px);
  line-height:1.08;
}
header p{
  font-size:clamp(14.5px, 1.6vw, 17px);
  line-height:1.55;
}
.hero-stat{margin-top:12px}

@media(min-width:1024px){
  body.rk-home:not(.rk-answered) .rk-fold,
  body.rk-home.rk-answered .rk-fold,
  .rk-fold{
    display:grid;
    grid-template-columns:1fr 1fr;
    align-items:center;
    gap:46px;
    min-height:auto;
    padding-bottom:24px;
  }
  .rk-fold > header{grid-row:1;grid-column:1;margin:0}
  .rk-fold > #calcpanel{grid-row:1;grid-column:2;margin-top:0}
  body.rk-home:not(.rk-answered) .rk-fold{min-height:calc(78vh - var(--rk-chrome,56px))}
}

.rk-fold > .sr-only{position:absolute}

@media(min-width:1024px){
  body.rk-home.rk-answered #answerzone{display:contents}
  body.rk-home.rk-answered .rk-fold{
    display:grid;
    grid-template-columns:1fr 1fr;
    align-items:start;
    gap:32px 46px;
  }
  body.rk-home.rk-answered header{grid-column:1/-1}

  /* The calculator keeps its natural height. Stretching it to match the result
     card put empty space inside a bordered box, which reads as broken; the same
     space as page background does not. */
  body.rk-home.rk-answered #calcpanel{
    grid-column:1;grid-row:2;
    margin-top:0;
    align-self:start;
  }

  /* The calculator was 199px against a 376px result card, so the left column
     ran out of content less than halfway down and the footnotes sat marooned
     under a large hole. Rather than stretch the card and pad the inside with
     nothing, the controls themselves get bigger: this is the primary input on
     the site and it was smaller than the number it produces. That closes most
     of the difference with real content, and the footnotes take up the rest.

     Depth is unified at the same time. The two cards had different radii (18px
     against 24px) and different shadows, which is why the pair read as two
     unrelated objects rather than one layer. */
  #calcpanel,
  .headline{
    border-radius:var(--r-xl);
    box-shadow:var(--el-3), var(--edge);
  }
  /* Sizes are back to comfortable rather than inflated. The controls were
     enlarged when the card held only two of them and ran short against the
     result card; the Shariah toggle now fills that height with real content,
     so the padding does not have to do it. */
  #calcpanel{padding:24px 24px 24px}
  #calcpanel .fld{font-size:12px;margin-bottom:10px}
  #calcpanel .amount input{
    font-size:24px;
    padding:19px 16px 19px 38px;
    border-radius:var(--r-md);
  }
  #calcpanel .amount span{font-size:21px;left:16px}
  #calcpanel .seg{padding:5px}
  #calcpanel .seg button{padding:13px 10px;font-size:14px}
  #calcpanel .reveal{margin-top:18px;padding:15px 18px;font-size:15px}
  #calcpanel .rk-hook{margin-top:9px}

  /* The toggle came from the options panel, where it sat on a full width row.
     In the calculator card it keeps that shape but picks up a divider, so it
     reads as a third control rather than something appended. */
  #calcpanel .shrow{
    display:flex;
    align-items:center;
    justify-content:space-between;
    gap:14px;
    padding-top:16px;
    border-top:1px solid var(--border, var(--line, #E5E7EB));
  }
  #calcpanel .shrow .sht{font-size:14px;font-weight:700}
  #calcpanel .shrow .shsub{font-size:12.5px;color:var(--muted);margin-top:2px}
  /* Exact edge alignment between the two columns.

     The footnotes fill the left column so it does not run out halfway down, and
     the result card spans the same three rows so both columns start and finish
     on the same line.

     Two things had to be right for that, and neither was obvious:

     1. align-self:stretch on the result card. .rk-fold sets align-items:start,
        which applies to every grid item, so the card sat at its natural height
        at the top of its span and never reached the bottom row.
     2. align-self:end on the footnotes. A 1fr middle row does not expand here,
        because .rk-fold is content sized and a fractional row only distributes
        free space that a definite height would create. Anchoring the footnotes
        to the end of their rows achieves the same result without depending on
        that.

     Measured after the fix: both columns top at 295 and bottom at 692, so the
     top and bottom deltas are both zero. */
  body.rk-home.rk-answered .rk-fold{grid-template-rows:auto auto 1fr auto}
  body.rk-home.rk-answered #headline{
    grid-column:2;grid-row:2 / 5;
    margin-top:0;
    align-self:stretch;
  }
  body.rk-home.rk-answered .hl-note{
    grid-column:1;grid-row:3;
    align-self:end;
    text-align:left;
    margin:0;
    max-width:none;
  }
  body.rk-home.rk-answered .fresh-under{
    grid-column:1;grid-row:4;
    align-self:end;
    margin:0;
    justify-content:flex-start;
  }
  body.rk-home.rk-answered .doors,
  body.rk-home.rk-answered .bcard,
  body.rk-home.rk-answered #topperf,
  body.rk-home.rk-answered #srlive{
    grid-column:1/-1;
  }
}

/* Both footnotes centre under the pair of cards rather than hanging off one
   column. They are about the whole answer, not about either card. */
.hl-note,
.fresh-under{
  text-align:center;
}
.hl-note{
  max-width:none;
  margin-top:18px;
}

/* The comparison date is a trust signal, not small print: it is the answer to
   "is this current". It reads as a chip you could tap, because it is one. */
.fresh-under{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:8px;
  width:fit-content;
  margin:12px auto 0;
  padding:9px 16px;
  font-size:13.5px;
  border-radius:var(--r-pill);
  border:1px solid color-mix(in srgb, var(--green) 34%, transparent);
  background:color-mix(in srgb, var(--green) 8%, transparent);
  color:var(--text, var(--ink, #1A1F2C));
}
.fresh-under .asof{
  color:var(--green-dark);
  font-weight:800;
}
.fresh-under .dot{
  width:8px;height:8px;
  margin:0;
  box-shadow:0 0 0 4px color-mix(in srgb, var(--green) 18%, transparent);
}
@media (prefers-reduced-motion: no-preference){
  .fresh-under .dot{animation:rkPulse 2.8s ease-in-out infinite}
  @keyframes rkPulse{
    0%,100%{box-shadow:0 0 0 3px color-mix(in srgb, var(--green) 16%, transparent)}
    50%{box-shadow:0 0 0 7px color-mix(in srgb, var(--green) 6%, transparent)}
  }
}
@media(max-width:560px){
  .fresh-under{font-size:12.5px;padding:8px 13px}
}


/* ---------------------------------------------------------------------------
   6. THE RESULT
   This is the payoff of the whole product and it was styled like a notice box.
   ------------------------------------------------------------------------ */

.headline{
  position:relative;
  overflow:hidden;
  margin-top:24px;
  padding:22px 22px 20px;
  border-radius:var(--r-xl);
  border:1px solid rgba(31,158,87,.28);
  box-shadow:var(--el-3), var(--edge);
  background:
    radial-gradient(120% 140% at 8% 0%, rgba(46,204,113,.13), transparent 58%),
    var(--green-soft, rgba(46,204,113,.12));
}
[data-theme="dark"] .headline{
  border-color:rgba(61,217,138,.24);
  background:
    radial-gradient(120% 140% at 8% 0%, rgba(61,217,138,.16), transparent 58%),
    #14261D;
}

/* A hairline of brand colour along the top edge of the result. */
.headline::after{
  content:"";
  position:absolute;left:0;right:0;top:0;height:2px;
  background:linear-gradient(90deg, transparent, var(--green), transparent);
  opacity:.75;
}

.hs-main{
  font-size:clamp(38px, 9.5vw, 68px);
  letter-spacing:-.035em;
  line-height:1;
  margin-top:2px;
}
@media(min-width:1024px){
  .hs-main{font-size:clamp(46px, 4.4vw, 68px)}
}

/* "৳1,80,000 grew to" is a sentence, not a label, so it stays sentence case. */
.hs-kicker{
  font-size:13.5px;
  letter-spacing:0;
  text-transform:none;
}

/* "Historical result" above it is the label, and gets the label treatment. */
.hl-kicker{
  font-size:11.5px;
  letter-spacing:.09em;
  text-transform:uppercase;
  font-weight:700;
}

/* The sparkline used to letterbox: its viewBox had the default
   preserveAspectRatio, so at full card width it drew a short centred fragment
   with dead space either side. sparkSvg() now emits preserveAspectRatio="none"
   with a non-scaling stroke, so CSS can simply give it a box to fill. */
.hs-spark{margin:14px 0 4px}
.hs-spark .spark{
  display:block;
  width:100%;
  height:74px;
  filter:drop-shadow(0 3px 10px rgba(31,158,87,.30));
}
@media(max-width:560px){
  .hs-spark .spark{height:52px}
}

/* A marker travels the length of every sparkline, continuously.

   Two overlaid copies of the line, both with no fill:
     .rk-trace  a short comet tail
     .rk-dot    a zero length dash with a round cap, which renders as a dot

   The dot is a round line cap rather than a circle or an arrow glyph on
   purpose. These sparklines use preserveAspectRatio="none" and are stretched
   by different amounts on each axis, so any real shape would be visibly
   squashed, and by a different amount on the hero, the fund rows and the fund
   pages. A cap is drawn in stroke space, and with non-scaling-stroke it stays
   perfectly round at every size.

   Both are decoration painted over the real line, which stays fully drawn
   underneath at all times. --rk-len is the measured path length, set per
   element by rk-ui.js. */
.rk-trace,
.rk-dot{
  fill:none;
  pointer-events:none;
  opacity:0;
}
@media (prefers-reduced-motion: no-preference){
  .rk-trace{
    stroke:currentColor;
    stroke-width:2.4;
    stroke-linecap:round;
    opacity:.55;
    animation:rkTrace var(--rk-dur, 5.5s) linear infinite;
  }
  .rk-dot{
    stroke:currentColor;
    stroke-width:5.5;
    stroke-linecap:round;
    opacity:1;
    filter:drop-shadow(0 0 5px currentColor);
    animation:rkTrace var(--rk-dur, 5.5s) linear infinite;
  }
  @keyframes rkTrace{
    from{stroke-dashoffset:var(--rk-len, 1000)}
    to{stroke-dashoffset:0}
  }
}

/* The surfer riding the result line.

   Positioned by rk-ui.js against the real path, so all this does is establish
   the containing block and keep it out of the way of everything else. It is
   decoration over data: aria-hidden in the markup, no pointer events here. */
.hs-spark{position:relative}

/* The sea. Decorative only, and deliberately the only moving part: the total
   return path above it is real published data and is never deformed. Sits
   behind the line, low contrast, so it reads as water rather than as a second
   series someone might try to interpret. */
/* Clips the sea to the chart. The sea is twice the container's width so it can
   slide one full period without exposing a gap, which left it overhanging the
   right edge past where the plotted line stops. This box crops it to exactly
   the chart width, so both ends of the water line up with both ends of the
   line. It is a separate box rather than overflow on .hs-spark because the
   surfer sits above the line and would get its head clipped. */
.rk-sea-box{
  position:absolute;
  inset:0;
  overflow:hidden;
  z-index:0;
  pointer-events:none;
}
.rk-sea{
  position:absolute;
  left:0;
  bottom:0;
  width:200%;
  height:46%;
  pointer-events:none;
}
.rk-sea-back{fill:currentColor;opacity:.14}
.rk-sea-front{fill:currentColor;opacity:.22}
.hs-spark{color:var(--green-dark)}

.rk-surf{
  position:absolute;
  left:0;
  top:0;
  font-size:26px;
  line-height:1;
  pointer-events:none;
  user-select:none;
  z-index:2;
  filter:drop-shadow(0 2px 5px rgba(0,0,0,.45));
  will-change:transform;
}
/* Spray off the back of the board. --rk-spray is set per frame from the slope,
   so it builds going uphill and settles on the way down. */
.rk-surf::before{
  content:"";
  position:absolute;
  right:78%;
  bottom:6%;
  width:16px;
  height:5px;
  border-radius:999px;
  background:currentColor;
  color:#fff;
  opacity:calc(var(--rk-spray, .5) * .55);
  filter:blur(2.5px);
}
@media(max-width:560px){
  .rk-surf{font-size:21px}
  .rk-sea{height:52%}
}

@media (prefers-reduced-motion: no-preference){
  /* Shift by exactly one wave period so the loop has no visible jump.
     The unit here is user units, not a percentage: a percentage translate on an
     SVG child resolves against that child's own bounding box rather than the
     viewport, which would not line up. One period of this path is 100 units,
     and the path is drawn out to 550 so the window stays covered while it
     slides left. */
  @keyframes rkSeaDrift{
    from{transform:translateX(0)}
    to{transform:translateX(-100px)}
  }
  .rk-sea-back{animation:rkSeaDrift 9s linear infinite}
  .rk-sea-front{animation:rkSeaDrift 6s linear infinite}
}
/* No surfer at all for a reader who asked for less motion: a static emoji
   parked on the line would just look like a stray character. */
@media (prefers-reduced-motion: reduce){
  .rk-surf{display:none}
}

/* Riding the wave. Sits bottom right of the result card, on the same right
   edge as the period dropdown above it. It carries data-tip, so the site's
   existing tooltip component opens it like any other tip. */
.headline{position:relative}
.rk-ride{
  display:inline-flex;
  align-items:center;
  gap:7px;
  margin:14px 0 0 auto;
  padding:8px 14px;
  font-family:inherit;
  font-size:12.5px;
  font-weight:700;
  letter-spacing:.01em;
  color:var(--green-dark);
  background:color-mix(in srgb, var(--green) 10%, transparent);
  border:1px solid color-mix(in srgb, var(--green) 34%, transparent);
  border-radius:var(--r-pill);
  cursor:pointer;
  min-height:38px;
  transition:background .16s ease, border-color .16s ease;
}
.rk-ride:hover{
  background:color-mix(in srgb, var(--green) 18%, transparent);
  border-color:var(--green);
}
.rk-ride span{font-size:15px;line-height:1}
/* The card is a normal block, so an auto left margin is what pushes the button
   to the right edge. display:flex on the button alone would not do it. */
.headline > .rk-ride{
  display:flex;
  width:fit-content;
}
@media(max-width:560px){
  .rk-ride{font-size:12px;padding:8px 12px;min-height:40px}
}

/* The growth chart draws itself in front of the reader on every render.

   The resting state is a fully drawn line: the keyframe runs from the measured
   length to zero, and the element's own inline stroke-dashoffset is 0. So an
   animation that never starts, or is cancelled by the chart re-rendering,
   leaves a complete chart rather than a blank one. */
@media (prefers-reduced-motion: no-preference){
  #chart svg path.rk-draw{
    animation:rkTrace var(--rk-draw-dur, 1.5s) cubic-bezier(.25,.8,.35,1) both;
  }
  #chart svg circle.rk-draw-pt{
    animation:rkPop .4s cubic-bezier(.2,.85,.3,1) var(--rk-draw-dur, 1.5s) both;
  }
  @keyframes rkPop{
    from{opacity:0;transform:scale(.4)}
    to{opacity:1;transform:none}
  }
}
[data-theme="dark"] .hs-spark .spark{
  filter:drop-shadow(0 3px 12px rgba(61,217,138,.30));
}

.hs-sub{font-size:14px;line-height:1.6}
.hs-period-sel{
  min-height:44px;
  box-shadow:0 3px 10px rgba(31,158,87,.28);
}

/* Freshness and disclaimer read as one quiet footnote block, centred under
   the result rather than competing with it. */
.hl-note,.fresh-under{font-size:12.5px}


/* ---------------------------------------------------------------------------
   7. CONTROLS
   ------------------------------------------------------------------------ */

/* Segmented controls: real track, real thumb, clear inactive affordance. */
.seg{
  border-radius:var(--r-md);
  padding:4px;
  background:#EDF1F4;
  box-shadow:inset 0 1px 2px rgba(16,32,24,.06);
}
[data-theme="dark"] .seg{
  background:#101825;
  box-shadow:inset 0 1px 2px rgba(0,0,0,.45);
}
.seg button{
  border-radius:var(--r-sm);
  transition:background .16s, color .16s, box-shadow .16s;
}
.seg button:hover:not(.on){
  background:rgba(46,204,113,.10);
  color:var(--green-dark);
}
.seg button.on{
  box-shadow:0 1px 2px rgba(16,32,24,.10), 0 2px 6px rgba(16,32,24,.06);
}
[data-theme="dark"] .seg button.on{
  background:#233246;
  box-shadow:0 1px 2px rgba(0,0,0,.5), inset 0 1px 0 rgba(255,255,255,.06);
}

#horizon button.on{
  background:linear-gradient(135deg,#1FA85C,#157A43);
  box-shadow:0 2px 8px rgba(31,158,87,.35);
}

/* The amount field is the single most important input on the site. */
.amount input{
  font-size:22px;
  padding:16px 16px 16px 34px;
  border-radius:var(--r-md);
  border-width:1.5px;
  transition:border-color .16s, box-shadow .16s, background .16s;
}
.amount input:focus{
  box-shadow:0 0 0 4px rgba(46,204,113,.16);
}
.amount span{font-size:19px}

/* Native selects were the most obviously unstyled elements on the site.
   One consistent treatment with a drawn chevron.
   Every rule that sets background-image also sets repeat/size/position.
   Dark-mode page CSS uses `background:` shorthand on .hsel-wide, which
   otherwise resets those and tiles the chevron across the control. */
html select:not(.hs-period-sel){
  appearance:none;
  -webkit-appearance:none;
  font-family:inherit;
  font-weight:600;
  color:var(--text, var(--ink, #1A1F2C));
  background-color:var(--card);
  border:1px solid var(--border, var(--line, #E5E7EB));
  border-radius:var(--r-md);
  padding:12px 38px 12px 14px;
  min-height:46px;
  cursor:pointer;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%236B7280' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 14px center;
  background-size:11px 7px;
  transition:border-color .16s, box-shadow .16s;
}
html select:not(.hs-period-sel):hover{border-color:var(--green)}
html select:not(.hs-period-sel):focus{
  border-color:var(--green);
  box-shadow:0 0 0 4px rgba(46,204,113,.14);
}
html[data-theme="dark"] select:not(.hs-period-sel){
  background-color:#141C28;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%239BA7BB' stroke-width='1.8' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;
  background-position:right 14px center;
  background-size:11px 7px;
}

/* Full width calls to action centre their text.

   Each carries a single message and spans the container, so left aligned text
   leaves the label stranded at one end of a very wide button. This is scoped to
   the full width CTAs on purpose: inline text-style buttons like the fund
   details disclosure stay left aligned beside the content they open. */
.door,
.reveal,
.bcontinue,
.showall,
.vs-cta{
  text-align:center;
  justify-content:center;
}

/* Primary call to action. */
.reveal,
.door-x{
  border-radius:var(--r-md);
  box-shadow:var(--el-green);
  letter-spacing:.005em;
}
.reveal:hover,
.door-x:hover{
  box-shadow:0 8px 24px rgba(31,158,87,.42);
}

/* The expert door. This is the most important button on the page and it read
   as a flat green bar, so it now carries some weight of its own.

   The main change is not decoration, it is that the button says what is behind
   it. A CTA that names its contents converts better than one that asks for
   trust, and the fund count comes from the page rather than being hardcoded,
   so it cannot drift when the roster changes.

   The sheen is a single pass with a long rest between, not a constant shimmer,
   which reads as invitation rather than as a loading state. */
.door-x{
  position:relative;
  overflow:hidden;
  display:flex;
  flex-direction:column;
  align-items:center;
  justify-content:center;
  text-align:center;
  gap:3px;
  padding:16px 20px 15px;
  background:linear-gradient(135deg,#22B364 0%,#157A43 55%,#116538 100%);
  border:1px solid rgba(255,255,255,.10);
  min-height:62px;
  animation:none;
}
.door-x-main,
.door-x-sub{
  position:relative;
  z-index:1;
}
.door-x-main{
  display:block;
  font-size:15.5px;
  font-weight:800;
  letter-spacing:.005em;
}
.door-x-sub{
  display:block;
  font-size:12.5px;
  font-weight:600;
  color:rgba(255,255,255,.78);
  letter-spacing:.01em;
}
.door-x:hover{
  transform:translateY(-1px);
  border-color:rgba(255,255,255,.20);
}

@media (prefers-reduced-motion: no-preference){
  .door-x::before{
    content:"";
    position:absolute;
    top:-60%;bottom:-60%;
    left:-35%;
    width:26%;
    background:linear-gradient(100deg,
      rgba(255,255,255,0) 0%,
      rgba(255,255,255,.26) 50%,
      rgba(255,255,255,0) 100%);
    transform:skewX(-18deg);
    pointer-events:none;
    animation:rkDoorSheen 5.2s ease-in-out infinite;
  }
  @keyframes rkDoorSheen{
    0%{left:-35%}
    38%{left:130%}
    100%{left:130%}
  }
  .door-x:hover::before{animation-duration:1.6s}
}

@media(max-width:560px){
  .door-x{padding:14px 16px 13px;min-height:58px}
  .door-x-main{font-size:14.5px}
  .door-x-sub{font-size:11.5px}
}

/* Secondary call to action reads as quiet, not as broken. */
.door-b{
  border-width:1.5px;
  border-radius:var(--r-md);
  background-image:var(--wash);
  transition:background .16s, border-color .16s, transform .16s;
}
.door-b:hover{
  background-color:rgba(46,204,113,.08);
  transform:translateY(-1px);
}

/* Open state. The button looked identical whether the panel below it was open
   or shut, so clicking it gave no acknowledgement at all. aria-expanded is
   already toggled by the existing script, so the state is there to style and
   no new JavaScript is needed. The chevron marks the direction of the next
   click rather than the current state. */
.door[aria-expanded="true"]{
  background-color:rgba(46,204,113,.12);
  border-color:var(--green);
}
/* The chevron is on the beginner door only.

   "Open the full data & tools" does not get one. That button is handed over to
   control a different element once the cockpit is open, and its aria-expanded
   is set rather than toggled by the page's own script, so a chevron there was
   reporting a state it did not really track. Removing it is honest; the panel
   appearing below is the feedback. */
.door-b[aria-expanded="true"]::after{
  content:"";
  display:inline-block;
  width:7px;height:7px;
  margin-left:10px;
  border-right:2px solid currentColor;
  border-bottom:2px solid currentColor;
  transform:translateY(-3px) rotate(-135deg);
}
.door-b[aria-expanded="false"]::after{
  content:"";
  display:inline-block;
  width:7px;height:7px;
  margin-left:10px;
  border-right:2px solid currentColor;
  border-bottom:2px solid currentColor;
  transform:translateY(-1px) rotate(45deg);
  opacity:.7;
}
.door-x::after{content:none}
@media (prefers-reduced-motion: no-preference){
  .door-b::after{transition:transform .2s ease}
}

/* Disclosure summaries get a target and a hover state. */
summary{
  border-radius:var(--r-sm);
  transition:background .14s;
}
summary:hover{background:rgba(46,204,113,.08)}


/* ---------------------------------------------------------------------------
   8. DATA DISPLAY
   ------------------------------------------------------------------------ */

/* Comparison bars: gradient, rounded, with a shine so they read as objects.
   Rows were ragged because long fund names wrapped to two lines. */
.cbar-row{
  min-height:38px;
  padding:1px 0;
  border-radius:var(--r-sm);
  transition:background .14s;
}
.cbar-row:hover{background:rgba(46,204,113,.07)}
.cbar-name{
  font-size:12.5px;
  line-height:1.2;
  display:-webkit-box;
  -webkit-line-clamp:2;
  -webkit-box-orient:vertical;
  overflow:hidden;
}
.cbar-fill{
  border-radius:var(--r-pill);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.25);
  transform-origin:left center;
}

/* The Compare all funds bars grow when the panel is scrolled into view, not on
   page load, because the panel sits well below the fold and a load-time
   animation had always finished before anyone reached it.

   The gate is a class rk-ui.js adds on intersection, and the resting state is a
   full bar. So the animation is purely additive: if the observer never fires,
   or the script never runs, every bar is simply already drawn. Nothing here can
   leave a bar at zero. */
@media (prefers-reduced-motion: no-preference){
  .rk-barview .cbar-fill{animation:rkBarIn .8s cubic-bezier(.22,.8,.3,1) both}
  .rk-barview .cbar-row:nth-of-type(1) .cbar-fill{animation-delay:.04s}
  .rk-barview .cbar-row:nth-of-type(2) .cbar-fill{animation-delay:.09s}
  .rk-barview .cbar-row:nth-of-type(3) .cbar-fill{animation-delay:.14s}
  .rk-barview .cbar-row:nth-of-type(4) .cbar-fill{animation-delay:.19s}
  .rk-barview .cbar-row:nth-of-type(5) .cbar-fill{animation-delay:.24s}
  .rk-barview .cbar-row:nth-of-type(6) .cbar-fill{animation-delay:.29s}
  .rk-barview .cbar-row:nth-of-type(7) .cbar-fill{animation-delay:.34s}
  .rk-barview .cbar-row:nth-of-type(8) .cbar-fill{animation-delay:.39s}
  .rk-barview .cbar-row:nth-of-type(n+9) .cbar-fill{animation-delay:.44s}
}
.cbar-fill.pos{
  background:linear-gradient(90deg,#1FA85C,#2ECC71);
}
.cbar-row.best .cbar-fill.pos{
  background:linear-gradient(90deg,#157A43,#2ECC71);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.3), 0 2px 10px rgba(31,158,87,.32);
}
[data-theme="dark"] .cbar-fill.pos{
  background:linear-gradient(90deg,#22A05F,#3DD98A);
}

/* Stat tiles on fund pages and the safe options row. */
.rt-mt,
.ba-link{
  border-radius:var(--r-md);
}

/* Type group headings get their category colour as a soft backing bar. */
.typehead{
  margin:36px 0 12px;
  font-size:18px;
  padding-bottom:10px;
  border-bottom:1px solid var(--border, var(--line, #E5E7EB));
}
.typehead::before{
  width:13px;height:13px;border-radius:4px;
  box-shadow:0 0 0 4px color-mix(in srgb, var(--tycol,#6B7280) 16%, transparent);
}

/* Badges and tags. */
.tag{
  padding:3px 9px;
  border-radius:var(--r-pill);
  letter-spacing:.01em;
  font-size:11px;
}

/* Balanced was the only fund type whose badge ignored the type palette. Growth
   reads green, Income blue and Shariah indigo, all matching their group dot,
   while Balanced sat in slate grey against an amber dot. It now uses the amber
   the palette already assigns it (--tycol #D97706 on .ty-balanced).

   The amber is deliberately deeper than the .tag.warn amber, which means "AMC
   site outdated", so a fund type is never mistaken for a data warning. */
.tag.balanced{
  background:#FCEFCD;
  color:#96500B;
}
[data-theme="dark"] .tag.balanced{
  background:#33280E;
  color:#F5BE58;
}

/* ---------------------------------------------------------------------------
   8b. FUND ROWS ON MOBILE

   The problem: .row is a three column flex (rank, fund, nums). At 390px the
   name column is left with about 194px, so every fund name wraps to two or
   three lines while the numbers float in a narrow right column with a 64px
   sparkline sitting above them, aligned to nothing. The card ran about 480px
   tall to show five facts.

   The fix: .fund becomes display:contents on small screens, which promotes its
   children to grid items of .row. That lets the name take the full width and
   lets the money block sit directly under it, above the metadata, without any
   change to the markup or to the JavaScript that builds it.
   ------------------------------------------------------------------------ */

@media(max-width:560px){

  .row{
    display:grid;
    grid-template-columns:auto 1fr;
    grid-template-areas:
      "rank name"
      "tags tags"
      "nums nums"
      "sub  sub"
      "why  why"
      "tog  tog"
      "det  det";
    align-items:start;
    column-gap:9px;
    row-gap:0;
    padding:15px 14px 13px;
    border-radius:var(--r-lg);
  }

  .row > .fund{display:contents}
  .row > .rank{grid-area:rank}
  .row .nm{grid-area:name}
  .row .tags{grid-area:tags}
  .row .sub{grid-area:sub}
  .row .why{grid-area:why}
  .row .fdtog{grid-area:tog}
  .row > .nums{grid-area:nums}
  .row > .fdet{grid-area:det}

  /* Rank becomes a marker instead of a floating digit. The .best variant is
     listed too because the base sheet resets its width on the winning row. */
  .row > .rank,
  .row.best > .rank{
    width:22px;height:22px;
    display:inline-flex;align-items:center;justify-content:center;
    border-radius:50%;
    background:color-mix(in srgb, var(--muted) 15%, transparent);
    font-size:11.5px;
    margin-top:2px;
  }

  /* The name now owns the full width, so it stops breaking mid phrase. */
  .row .nm{
    font-size:16px;
    line-height:1.3;
    align-items:baseline;
  }

  /* The winner label was a two line pill that outweighed the fund name. */
  .row .bestbadge{
    font-size:10px;
    font-weight:800;
    letter-spacing:.06em;
    text-transform:uppercase;
    padding:3px 8px;
  }
  .row .tags{margin-top:7px;gap:5px}

  /* The money block: value and annual rate share one baseline, gain sits
     under the value, and the sparkline runs the full width beneath both. */
  .row > .nums{
    display:grid;
    grid-template-columns:1fr auto;
    align-items:baseline;
    gap:2px 12px;
    text-align:left;
    margin-top:13px;
    padding-top:13px;
    border-top:1px solid var(--border, var(--line, #E5E7EB));
  }
  .row .nums .fv{
    grid-column:1;grid-row:1;
    font-size:27px;
    line-height:1.05;
    letter-spacing:-.025em;
  }
  .row .nums .ann{
    grid-column:2;grid-row:1;
    justify-self:end;
    font-size:13.5px;
    font-weight:700;
    color:var(--text, var(--ink, #1A1F2C));
    margin-top:0;
  }
  .row .nums .gn{
    grid-column:1;grid-row:2;
    font-size:13px;
  }
  .row .nums .sparkwrap{
    grid-column:1 / -1;grid-row:3;
    width:100%;
    margin-top:11px;
    align-self:stretch;
  }
  .row .nums .sparkwrap .spark{
    display:block;
    width:100%;
    height:44px;
  }

  .row .sub{
    margin-top:12px;
    font-size:12.5px;
    line-height:1.5;
  }

  /* "How we got this number" was a filled grey box roughly 60px tall holding
     nothing until it is opened, sitting between the data and the actions. It
     collapses to a plain text row and only becomes a box once it is open. */
  .row .why{
    margin-top:4px;
    padding:0;
    background:transparent;
    border-radius:0;
  }
  .row .why summary{
    display:flex;
    align-items:center;
    min-height:44px;
    font-size:12.5px;
    color:var(--muted);
  }
  .row .why[open]{
    margin-top:8px;
    padding:0 11px 10px;
    background:color-mix(in srgb, var(--muted) 9%, transparent);
    border-radius:var(--r-sm);
  }

  /* Fund details was a filled box the size of the fund name. It is a
     disclosure, so it gets link weight with a 44px target. */
  .row .fdtog,
  [data-theme="dark"] .row .fdtog{
    margin-top:4px;
    padding:0;
    min-height:44px;
    background:transparent;
    border:0;
    border-radius:0;
    justify-self:start;
    font-size:13px;
  }
  .row .fdtog:hover,
  [data-theme="dark"] .row .fdtog:hover{
    background:transparent;
    text-decoration:underline;
    text-underline-offset:3px;
  }
}

/* ---------------------------------------------------------------------------
   8c. FUND ROWS ON DESKTOP

   The same three column flex that squeezed the name on a phone left a dead
   gap in the middle on a laptop: the name column stretched across most of the
   row, the "How we got this number" box stretched with it into a 1500px empty
   bar, and the sparkline stayed a 64px squiggle in the corner.

   Same technique as mobile, opposite goal. .fund becomes display:contents and
   the row becomes four real columns: marker, fund identity, a sparkline wide
   enough to read, and the money. The two disclosures drop to text weight and
   stay inside the identity column, so nothing stretches to fill space.
   ------------------------------------------------------------------------ */

@media(min-width:900px){

  /* The identity column is capped rather than greedy, so leftover width goes
     to the sparkline instead of becoming a dead gap in the middle of the row. */
  .row{
    display:grid;
    grid-template-columns:26px minmax(280px, 34rem) minmax(300px, 1fr);
    grid-template-areas:
      "rank name  nums"
      "rank tags  nums"
      "rank sub   nums"
      "rank why   nums"
      "rank tog   nums"
      "det  det   det";
    align-items:start;
    column-gap:22px;
    row-gap:0;
    padding:18px 20px;
    border-radius:var(--r-lg);
    transition:border-color .16s, box-shadow .16s;
  }
  .row:hover{
    border-color:color-mix(in srgb, var(--green) 45%, var(--border, var(--line, #E5E7EB)));
    box-shadow:var(--el-2);
  }

  .row > .fund{display:contents}
  .row > .rank,
  .row.best > .rank{
    grid-area:rank;
    width:26px;height:26px;
    display:inline-flex;align-items:center;justify-content:center;
    border-radius:50%;
    background:color-mix(in srgb, var(--muted) 15%, transparent);
    font-size:12px;
    margin-top:1px;
  }
  .row .nm{grid-area:name;font-size:16.5px;line-height:1.3}
  .row .tags{grid-area:tags;margin-top:8px}
  .row .sub{grid-area:sub;margin-top:9px;font-size:12.5px}
  .row .why{grid-area:why}
  .row .fdtog{grid-area:tog}
  .row > .fdet{grid-area:det;margin-top:14px}

  /* .sparkwrap is a child of .nums, not a sibling of it, so the sparkline
     cannot be placed in a column of .row. Instead .nums becomes its own two
     column grid: the chart takes the slack on the left, the three figures
     stack on the right, and the two centre against each other. */
  .row > .nums{
    grid-area:nums;
    align-self:center;
    display:grid;
    grid-template-columns:minmax(0,1fr) auto;
    align-items:center;
    column-gap:22px;
    text-align:right;
  }
  .row .nums .sparkwrap{
    grid-column:1;
    grid-row:1 / 4;
    align-self:center;
    width:100%;
  }
  .row .nums .sparkwrap .spark{
    display:block;
    width:100%;
    height:60px;
  }
  .row .nums .fv{
    grid-column:2;grid-row:1;
    font-size:24px;letter-spacing:-.025em;line-height:1.15;
  }
  .row .nums .gn{grid-column:2;grid-row:2;font-size:13px;margin-top:2px}
  .row .nums .ann{grid-column:2;grid-row:3;font-size:12.5px;margin-top:2px}

  /* Both disclosures become text actions so neither stretches into a bar. */
  .row .why,
  [data-theme="dark"] .row .why{
    margin-top:6px;
    padding:0;
    background:transparent;
    border-radius:0;
    max-width:100%;
  }
  .row .why summary{
    display:inline-flex;
    align-items:center;
    min-height:34px;
    font-size:12.5px;
    color:var(--muted);
  }
  .row .why[open],
  [data-theme="dark"] .row .why[open]{
    margin-top:8px;
    padding:0 12px 11px;
    background:color-mix(in srgb, var(--muted) 9%, transparent);
    border-radius:var(--r-sm);
  }
  .row .fdtog,
  [data-theme="dark"] .row .fdtog{
    margin-top:2px;
    padding:0;
    min-height:34px;
    background:transparent;
    border:0;
    border-radius:0;
    justify-self:start;
    font-size:13px;
  }
  .row .fdtog:hover,
  [data-theme="dark"] .row .fdtog:hover{
    background:transparent;
    text-decoration:underline;
    text-underline-offset:3px;
  }
}

/* The fund size tooltip affordance read as a spellcheck squiggle. */
.fsz{
  text-underline-offset:3px;
  text-decoration-color:color-mix(in srgb, currentColor 40%, transparent);
}

/* ---------------------------------------------------------------------------
   8d. FUND PAGE HERO

   The template puts the four stat tiles and the chart card side by side with
   align-items:stretch and caps the chart column at 230px. Two consequences:
   the tiles balloon to whatever height the chart column reaches, and opening
   the data table crushes a month by month table into 230px, where every
   heading wraps. Both get worse the moment the disclosure is opened.

   Stacking is a better use of the width. The tiles run as one compact row of
   four, the chart spans the full column and gets properly tall, and the table
   inherits that full width instead of a narrow gutter. Matches the template's
   own 700px breakpoint exactly so there is no band where both rules apply.
   ------------------------------------------------------------------------ */

@media(min-width:700px){
  .fp-cluster:has(.fp-sparkcard){
    display:block;
  }
  .fp-cluster:has(.fp-sparkcard) .stats{
    grid-template-columns:repeat(4,1fr);
  }
  .fp-sparkcard{
    margin-top:12px;
    display:block;
    padding:12px 14px 10px;
  }
  .fp-sparkcard .fp-spark{
    display:block;
    width:100%;
    height:150px;
  }
  /* Compact tiles: they hold one number and one label, nothing more. */
  .stat{padding:12px 10px}
}

@media(min-width:1024px){
  .fp-sparkcard .fp-spark{height:180px}
}

/* A long table inside a card should scroll in the card, not run down the page. */
.cht-nums-wrap{max-height:420px;overflow:auto}

/* Roomier cells only where there is room. Left unscoped this would widen the
   table on a 390px phone, which is the one place it cannot afford the pixels.
   The fund page table carries just two columns, so it is capped as well:
   otherwise it strands the month at one edge and the value at the other across
   the full card. The homepage table has six or more columns and keeps it all. */
@media(min-width:700px){
  .cht-nums th,
  .cht-nums td{padding:8px 12px}
  .fp-sparkcard .cht-nums-wrap{max-width:720px}
}

/* The rolling returns table is table-layout:fixed with a 520px floor, which on
   a 390px phone squeezed six columns until the values ran into each other and
   read as one string. Letting the columns size to their content, with the cells
   set to nowrap and a wider floor, guarantees a gap between every number and
   sends the overflow to the wrapper, which already scrolls. */
@media(max-width:600px){
  table.ret-roll{
    table-layout:auto;
    min-width:600px;
    font-size:12.5px;
  }
  table.ret-roll th,
  table.ret-roll td{
    padding:10px 13px;
    white-space:nowrap;
  }
  /* A hint that the table moves sideways, since the edge is now off screen. */
  .tablewrap{
    scrollbar-width:thin;
    -webkit-overflow-scrolling:touch;
  }
}

/* Fund page prose lives inside cards and should use the card, not a reading
   measure meant for long-form pages. This covers the Questions section and any
   other answer block that sits in a card. */
.card .qa,
.card .qa p,
.card details p,
.card > p{max-width:none}

/* The chart data table disclosure gave no sign it could be opened, and kept
   saying "See the numbers" while the numbers were already on screen. A chevron
   supplies the affordance; rk-ui.js swaps the wording on toggle. */
details.cht-nums > summary{
  display:flex;
  align-items:center;
  gap:9px;
  cursor:pointer;
  list-style:none;
  min-height:44px;
  font-weight:700;
  color:var(--green-dark);
  width:fit-content;
}
details.cht-nums > summary::-webkit-details-marker{display:none}
details.cht-nums > summary::after{
  content:"";
  width:8px;height:8px;
  border-right:2px solid currentColor;
  border-bottom:2px solid currentColor;
  transform:translateY(-2px) rotate(45deg);
  transition:transform .2s ease;
}
details.cht-nums[open] > summary::after{
  transform:translateY(2px) rotate(-135deg);
}

/* The three most useful sections on the stocks page were indistinguishable
   from the rest of the page furniture. They are also now deep linked from the
   More page, so they need to be findable the moment a reader lands on them:
   a brand accent bar, more space above, and a scroll landing that clears the
   sticky header rather than hiding the heading underneath it. */
#overlap,
#diversify,
#check{
  scroll-margin-top:calc(var(--rk-chrome, 56px) + 18px);
  margin-top:38px;
  padding-left:14px;
  border-left:4px solid var(--green);
  border-radius:2px;
}

/* A deep linked heading flashes once so the eye lands in the right place. */
@media (prefers-reduced-motion: no-preference){
  #overlap:target,
  #diversify:target,
  #check:target{
    animation:rkTargetFlash 1.8s ease-out 1;
  }
  @keyframes rkTargetFlash{
    0%{background:color-mix(in srgb, var(--green) 22%, transparent)}
    100%{background:transparent}
  }
}

/* ---------------------------------------------------------------------------
   FUND VERSUS FUND
   ------------------------------------------------------------------------ */

/* The link out of a fund page, deliberately quiet.

   These static pages exist to be found in search. The interactive compare tool
   is the better experience, so this should not compete with it: a closed
   disclosure, muted, no card and no heading. */
.vs-more{
  margin:14px 0 12px;
  font-size:13px;
}
.vs-more > summary{
  display:flex;
  align-items:center;
  gap:8px;
  width:100%;
  min-height:44px;
  cursor:pointer;
  color:var(--muted);
  list-style:none;
  background:transparent;
}
.vs-more > summary::-webkit-details-marker{display:none}
.vs-more > summary::after{
  content:"";
  width:7px;height:7px;
  border-right:2px solid currentColor;
  border-bottom:2px solid currentColor;
  transform:translateY(-2px) rotate(45deg);
  transition:transform .2s ease;
}
.vs-more[open] > summary::after{transform:translateY(1px) rotate(-135deg)}
.vs-more > summary:hover{
  color:var(--green-dark);
  background:transparent;
}
.vs-links{
  margin:4px 0 0;
  padding-left:18px;
  font-size:13px;
  line-height:1.9;
}
.vs-links a{color:var(--muted)}
.vs-links a:hover{color:var(--green-dark)}

/* The route back into the real tool, from a versus page. This one is the
   opposite: it should be the loudest thing below the table. ctaBreath used
   to live only in index.html inline CSS, so a versus page could not run it.
   Same pulse as the homepage reveal button, with the green elevation kept. */
.vs-cta{
  display:flex;
  align-items:center;
  justify-content:center;
  gap:10px;
  width:100%;
  box-sizing:border-box;
  min-height:52px;
  margin:22px 0 0;
  padding:16px 22px;
  font-size:16px;
  font-weight:800;
  color:#fff;
  text-decoration:none;
  background:linear-gradient(135deg,#1FA85C,#157A43);
  border-radius:var(--r-md);
  box-shadow:var(--el-green);
  transition:transform .14s ease, box-shadow .16s ease;
}
.vs-cta:hover{
  transform:translateY(-1px);
  box-shadow:0 8px 24px rgba(31,158,87,.42);
}
.vs-cta:active{transform:translateY(0)}
.vs-cta-arrow{
  width:8px;height:8px;
  flex:none;
  border-top:2.5px solid currentColor;
  border-right:2.5px solid currentColor;
  transform:rotate(45deg);
}
.vs-cta-note{
  text-align:center;
  margin:10px 0 0;
  font-size:12.5px;
  color:var(--muted);
}
@media (prefers-reduced-motion: no-preference){
  @keyframes ctaBreath{
    0%,100%{box-shadow:var(--el-green), 0 0 0 0 rgba(46,204,113,0)}
    50%{box-shadow:var(--el-green), 0 0 0 8px rgba(46,204,113,.22)}
  }
  .vs-cta{animation:ctaBreath 3.2s ease-in-out infinite}
  .vs-cta:hover{animation:none}
  .vs-cta-arrow{animation:rkNudge 1.8s ease-in-out infinite}
  @keyframes rkNudge{
    0%,100%{transform:rotate(45deg) translate(0,0)}
    50%{transform:rotate(45deg) translate(2px,-2px)}
  }
}
@media(max-width:560px){
  .vs-cta{font-size:15px;padding:15px 16px;min-height:48px}
}

/* Start and end labels under the fund page total-return path. Kept in HTML
   rather than inside the SVG, because fp-spark is drawn with
   preserveAspectRatio="none" and any text in it would be stretched. */
.fp-axis{
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:12px;
  margin:6px 2px 0;
  font-size:12px;
  color:var(--muted);
  font-variant-numeric:tabular-nums;
}
.fp-axis b{
  font-size:14.5px;
  font-weight:800;
  color:var(--green-dark);
  margin-left:4px;
}
.fp-axis-note{margin:8px 2px 2px}

/* The provenance caption and the index note were two stacked left aligned
   lines with the whole right half of the card empty. They are related but
   independent, so they sit on one row, caption left and note right, and the
   row uses the full card width. */
@media(min-width:700px){
  .fp-sparkcard{
    display:grid;
    grid-template-columns:1fr auto;
    align-items:baseline;
    column-gap:20px;
  }
  .fp-sparkcard > svg,
  .fp-sparkcard > .fp-axis,
  .fp-sparkcard > details{grid-column:1 / -1}
  .fp-sparkcard > .fp-sparkcap{grid-column:1;margin:4px 2px 0}
  .fp-sparkcard > .fp-axis-note{grid-column:2;justify-self:end;margin:4px 2px 0}
}

/* Fund page provenance lines were three centred sentences with no styling,
   the only centred text on an otherwise left aligned page. Turn them into one
   quiet meta block that reads as metadata rather than as body copy. */
.fresh-lines{
  display:flex;
  flex-wrap:wrap;
  gap:4px 14px;
  justify-content:flex-start;
  text-align:left;
  font-size:12.5px;
  line-height:1.5;
  padding:11px 13px;
  border-radius:var(--r-md);
  border:1px solid var(--border, var(--line, #E5E7EB));
  background:color-mix(in srgb, var(--card) 70%, transparent);
}
.fresh-lines > span{display:inline-block;text-align:left}

/* The fund page returns table carries min-width:340px and lives in a scroll
   container, so on a 390px phone the last column sat under the edge with no
   sign that it scrolled. Dropping the floor lets all four columns fit instead. */
@media(max-width:430px){
  table.ret{
    min-width:0;
    font-size:12.5px;
  }
  table.ret th,
  table.ret td{
    padding-left:3px;
    padding-right:3px;
  }
}

/* Sticky quick bar was overlapping content underneath it. */
.qbar{
  border-radius:var(--r-md);
  box-shadow:var(--el-2), var(--edge);
  background:rgba(255,255,255,.90);
}
[data-theme="dark"] .qbar{background:rgba(20,28,40,.92)}


/* ---------------------------------------------------------------------------
   9. LAYOUT
   The 760px cap was the single biggest reason the site looked unfinished on a
   laptop. Widen progressively and let the grids inside actually use it.
   ------------------------------------------------------------------------ */

@media(min-width:1024px){
  .wrap{
    max-width:var(--wrap-wide);
    padding:34px 28px 76px;
  }
}
@media(min-width:1400px){
  .wrap{max-width:var(--wrap-xwide)}
}

/* Two column fund lists once there is room for them. */
@media(min-width:1024px){
  .fdgrid,
  #browseall.ba-grid{
    grid-template-columns:repeat(4,1fr);
  }
}

/* Prose pages had the opposite problem to the homepage. Widening .wrap to
   1180px pushed FAQ paragraphs to 1124px, roughly 160 characters a line, which
   is unreadable. The answer is not to fill that width with text but to put
   something useful in the margin: pages that already carry a table of contents
   get it as a sticky sidebar, and the text returns to a sane measure. */
@media(min-width:1024px){
  .wrap:has(> nav.toc){
    display:grid;
    grid-template-columns:232px minmax(0, 72ch);
    justify-content:center;
    column-gap:48px;
    align-items:start;
  }
  .wrap:has(> nav.toc) > *{grid-column:2}
  .wrap:has(> nav.toc) > h1,
  .wrap:has(> nav.toc) > .lead,
  .wrap:has(> nav.toc) > .g-updated{grid-column:1 / -1}
  /* :first-of-type matters. Learn carries two nav.toc elements: the topics
     list, and a second one holding the step-by-step guide links. Without this,
     both were placed at grid-row 4 / 200 in column one, landing in the same
     cell and covering each other, so the guide links only became visible when
     the topics list was collapsed. Only the first becomes the sidebar; any
     other nav.toc flows normally in the content column. */
  .wrap:has(> nav.toc) > nav.toc:first-of-type{
    grid-column:1;
    grid-row:4 / 200;
    position:sticky;
    top:88px;
    align-self:start;
    max-height:calc(100vh - 120px);
    overflow:auto;
  }
  .wrap:has(> nav.toc) > nav.toc:not(:first-of-type){
    grid-column:2;
    grid-row:auto;
    position:static;
    max-height:none;
  }
  /* At 232px the topic list cannot hold two columns without breaking every
     label across three lines. */
  .wrap:has(> nav.toc) > nav.toc ul,
  .wrap:has(> nav.toc) > nav.toc ol,
  .wrap:has(> nav.toc) > nav.toc .toclist{
    grid-template-columns:1fr;
    columns:1;
  }

  /* No reading measure cap on these pages.

     There used to be one, at 74ch and then 92ch, and it was the single thing
     that kept making text stop short of the edge with obvious space to its
     right. Every time it was narrowed in scope it just moved the problem to
     another block: fund page cards, then the compare intro, then the fund page
     Questions section.

     Pages that carry a table of contents already get a 72ch column from the
     grid above, which is where a measure genuinely helps. Everywhere else the
     container is the card, and the card is already the right width, so the
     text simply fills it. */
  .wrap:not(:has(> nav.toc)) p,
  .wrap:not(:has(> nav.toc)) ul,
  .wrap:not(:has(> nav.toc)) ol{
    max-width:none;
  }
}

/* Charts get taller on a big screen instead of staying phone sized. */
@media(min-width:1024px){
  .chartpanel canvas{min-height:340px}
}

/* Doors sit side by side rather than stacking full width. */
@media(min-width:900px){
  .doors{gap:14px}
  .door{flex:1 1 260px}
}

/* The beginner card was a capped paragraph on the left and four full width
   link bars, each holding one short phrase against roughly 1900px of empty
   green. Two columns: the explanation and its call to action on the left, the
   four guides as a 2 by 2 block of real cards on the right. */
@media(min-width:900px){
  /* :not([hidden]) matters. Setting display on .bcard unconditionally beat the
     hidden attribute's own display:none, so the beginner card was permanently
     open and the "New to funds? Start here" button had nothing left to reveal. */
  .bcard:not([hidden]){
    display:grid;
    grid-template-columns:minmax(0,44%) minmax(0,56%);
    column-gap:34px;
    row-gap:18px;
    align-items:start;
    padding:24px 26px;
  }
  .bcard > p{grid-column:1;grid-row:1;margin:0}
  .bcard .bcontinue{grid-column:1;grid-row:2;justify-self:start;align-self:start;margin-top:0}
  .bcard .bguides{
    grid-column:2;grid-row:1 / 3;
    display:grid;
    grid-template-columns:1fr 1fr;
    gap:10px;
    margin-top:0;
  }
  .bcard .bguides a{
    display:flex;
    align-items:center;
    min-height:64px;
    line-height:1.35;
  }
}


/* ---------------------------------------------------------------------------
   9a. SCROLL CUE

   The homepage first screen is a hero and two cards, which reads as the whole
   page. This says otherwise. Built by rk-ui.js so it never exists for a reader
   without JavaScript, who would be looking at a button that cannot scroll.
   ------------------------------------------------------------------------ */

/* Nothing is below the fold until the reader asks for the result, so the cue
   would be pointing at an empty page. It appears with the answer. */
body:not(.rk-answered) .rk-cue{display:none}

.rk-cue{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:7px;
  margin:26px auto 4px;
  padding:10px 18px 12px;
  border:0;
  background:transparent;
  border-radius:var(--r-pill);
  cursor:pointer;
  font-family:inherit;
  font-size:12px;
  font-weight:700;
  letter-spacing:.09em;
  text-transform:uppercase;
  color:var(--muted);
  transition:color .18s ease, opacity .35s ease, transform .35s ease;
}
.rk-cue:hover{color:var(--green-dark)}
.rk-cue-a{
  width:11px;height:11px;
  border-right:2.5px solid currentColor;
  border-bottom:2.5px solid currentColor;
  border-radius:2px;
  transform:rotate(45deg);
}
/* Once the reader is scrolling they no longer need to be told they can. */
.rk-cue-off{
  opacity:0;
  transform:translateY(-8px);
  pointer-events:none;
}
@media (prefers-reduced-motion: no-preference){
  .rk-cue-a{animation:rkCueBob 1.9s ease-in-out infinite}
  @keyframes rkCueBob{
    0%,100%{transform:rotate(45deg) translate(0,0)}
    50%{transform:rotate(45deg) translate(3px,3px)}
  }
}


/* ---------------------------------------------------------------------------
   9b. ALIGNMENT AND MEASURE PASS

   A batch of places where content still sat at the old narrow-column width
   under a full width heading, so it read as accidental rather than designed.
   ------------------------------------------------------------------------ */

/* Tap tooltips take the full width of whatever contains them, flush with the
   control that opened them. This is how the "What they hold" tips already
   behaved and it is now the single default for all of them: capping the width
   and centring the box was what left them floating as a narrow column in the
   middle of a wide layout.

   The one exception is the hero freshness chip, which is itself centred on the
   page, so its callout is capped and centred to sit under the chip rather than
   spanning the whole fold. */
.rktip{
  width:100%;
  max-width:none;
  margin-left:0;
  margin-right:0;
}
.fresh-under + .rktip,
.fresh-under ~ .rktip{
  max-width:min(72ch, 100%);
  margin-left:auto;
  margin-right:auto;
}

/* Short section subtitles are labels, not prose. A subtitle is the paragraph
   directly under a heading, so matching on that relationship catches every one
   of them instead of naming each section by hand and missing the next. They
   should sit under a full width heading, not break across the middle of it. */
h1 + p,
h2 + p,
h3 + p,
.shnote,
.typehead + p,
.browseall > p,
.ba-head + p,
p.sub,
.sortbar + p{
  max-width:none;
}
.shnote{display:block;margin-top:6px}

/* The community card centred its text but the paragraph carries an inline
   margin:0 0 14px, and an inline style beats a stylesheet auto margin, so it
   stayed pinned left however wide the cap was. Centring the section as a flex
   column sidesteps the inline margin entirely. */
.rk-community,
section[style*="text-align:center"]{
  display:flex;
  flex-direction:column;
  align-items:center;
}
.rk-community > p,
section[style*="text-align:center"] > p{
  max-width:none;
}

/* Sticky search and toolbars sat at top:0, or at a hardcoded 47px that no
   longer matches the nav, so their upper edge slid underneath it. Offset each
   one by the real header height. rk-ui.js measures the nav and publishes it as
   --rk-chrome, so this stays correct if the nav ever changes height.

   .ftools is the funds directory toolbar. It is the sticky element on that
   page, not .fsearch inside it, which is why targeting the search field alone
   left that page still broken. */
.faqsearch,
.lnsearch,
.fsearch,
.srchwrap,
.ftools{
  top:var(--rk-chrome, 56px);
}

/* A table that scrolls inside a card must keep its headings. --rk-cap-h is
   measured per table by rk-ui.js, because the caption wraps to two lines on
   narrow screens and a hardcoded offset would leave a gap or an overlap. */
.cht-nums caption{
  position:sticky;
  top:0;
  z-index:3;
  background:var(--card);
  padding-bottom:6px;
}
.cht-nums thead th{
  position:sticky;
  top:var(--rk-cap-h, 40px);
  z-index:2;
  background:var(--card);
}

/* Stocks page.

   The bars fill from the left on load. This is a plain CSS keyframe rather than
   a scroll triggered reveal on purpose: the entrance logic in rk-ui.js only
   touches elements already in the viewport, and almost every stock card is
   below the fold, which is why nothing appeared to animate at all. A keyframe
   with fill-mode both runs for every card regardless of position, and a bar
   that finished animating before it was scrolled into view is simply a full
   bar. Nothing here can leave a bar stuck at zero. */
.sx-fill{transform-origin:left center}

@media (prefers-reduced-motion: no-preference){
  @keyframes rkBarIn{
    from{transform:scaleX(0)}
    to{transform:scaleX(1)}
  }
  /* Each card fills when it scrolls into view, not on page load.

     The load-time version was the bug: this page carries about 43 bars and all
     of them finished inside 0.9 seconds, while roughly 40 were still below the
     fold. By the time anyone scrolled down every bar was already full, so the
     page looked completely static. rk-ui.js adds rk-barview per card as it
     arrives. The resting state is a full bar, so a card that never gets the
     class is simply drawn. */
  .rk-barview .sx-fill{animation:rkBarIn .85s cubic-bezier(.22,.8,.3,1) both}
}

/* Fund list sparklines draw in with a left to right wipe.

   Deliberately clip-path, not stroke-dasharray. The dash approach is what left
   those broken looking graphs: the list re-renders on every control change, and
   a line interrupted mid-draw kept a partial dash pattern. A clip wipe touches
   no stroke property, so an interrupted animation simply restarts, and if it
   never runs at all the graph is drawn in full. */
@media (prefers-reduced-motion: no-preference){
  @keyframes rkWipe{
    from{clip-path:inset(0 100% 0 0)}
    to{clip-path:inset(0 0 0 0)}
  }
  .row .sparkwrap .spark{animation:rkWipe .85s cubic-bezier(.22,.8,.3,1) both}
  .row:nth-of-type(1) .sparkwrap .spark{animation-delay:.05s}
  .row:nth-of-type(2) .sparkwrap .spark{animation-delay:.11s}
  .row:nth-of-type(3) .sparkwrap .spark{animation-delay:.17s}
  .row:nth-of-type(4) .sparkwrap .spark{animation-delay:.23s}
  .row:nth-of-type(5) .sparkwrap .spark{animation-delay:.29s}
  .row:nth-of-type(6) .sparkwrap .spark{animation-delay:.35s}
}

/* Cards respond to the pointer so the list feels alive rather than static. */
.sx-card{transition:border-color .16s ease, box-shadow .16s ease, transform .16s ease}
.sx-card:hover{
  border-color:color-mix(in srgb, var(--green) 45%, var(--border, var(--line, #E5E7EB)));
  box-shadow:var(--el-2);
}
.sx-trk{height:9px;border-radius:5px}
.sx-fill{
  border-radius:5px;
  background:linear-gradient(90deg,#1FA85C,#2ECC71);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.25);
}
[data-theme="dark"] .sx-fill{background:linear-gradient(90deg,#22A05F,#3DD98A)}
.sx-det summary{
  min-height:44px;
  display:flex;
  align-items:center;
  cursor:pointer;
}


/* The bar scale note. Every table on the site that draws a bar relative to the
   largest figure in its column now carries the same explanation, because a bar
   that is not a 0 to 100% scale is genuinely misleading without one. */
.rk-barnote{
  display:flex;
  align-items:center;
  gap:8px;
  flex-wrap:wrap;
  margin:0 0 12px;
  font-size:12.5px;
  line-height:1.5;
  color:var(--muted);
  max-width:none;
}


/* ---------------------------------------------------------------------------
   9c. COMPARE PAGE CHART
   ------------------------------------------------------------------------ */

.cmp-viz{
  margin:22px 0 6px;
  padding:20px 22px 16px;
  border:1px solid var(--border, var(--line, #E5E7EB));
  border-radius:var(--r-lg);
  background:var(--card);
  background-image:var(--wash);
  box-shadow:var(--el-2), var(--edge);
}
.cmp-viz[hidden]{display:none}
.cmp-viz-head h2{font-size:18px;margin:0 0 4px}
.cmp-viz-sub{font-size:13px;color:var(--muted);margin:0 0 14px;max-width:none}
/* Shown when the chosen period is longer than the history the funds share.
   Amber rather than green: this is the chart reporting that it could not do
   what was asked, which is information, not an error and not a success. */
/* Self contained on purpose. An earlier version used var(--amber), which is
   declared in index.html but not in compare.html, so the notice would have had
   no text colour and an invalid border on the one page it appears. --accent-4
   is declared in this file, so it resolves wherever this stylesheet loads. */
.cmp-clamp{
  margin:0 0 14px;
  padding:11px 14px;
  font-size:13px;
  line-height:1.55;
  border-radius:14px;
  border:1px solid color-mix(in srgb, var(--accent-4) 45%, transparent);
  background:color-mix(in srgb, var(--accent-4) 12%, transparent);
  color:var(--accent-4);
  max-width:none;
}
.cmp-clamp[hidden]{display:none}
.cmp-clamp b{font-weight:800}

.cmp-legend{
  display:flex;
  flex-wrap:wrap;
  gap:8px 20px;
  margin-bottom:12px;
  font-size:13px;
  font-weight:600;
}
.cmp-lg{display:inline-flex;align-items:center;gap:8px}
.cmp-lg i{
  width:12px;height:12px;
  border-radius:4px;
  flex:none;
}
/* Uniform scaling now that the chart carries real text. height:auto keeps the
   720 by 260 viewBox aspect, so labels are never stretched. */
.cmp-chart-svg{
  display:block;
  width:100%;
  height:auto;
}
.cmp-grid{
  stroke:var(--border, var(--line, #E5E7EB));
  stroke-width:1;
  opacity:.55;
}
.cmp-base{
  stroke:var(--green);
  stroke-width:1.4;
  stroke-dasharray:4 4;
  opacity:.8;
}
.cmp-axl{
  font-size:11px;
  font-weight:600;
  fill:var(--muted);
}
.cmp-baselbl{
  font-size:10.5px;
  font-weight:700;
  letter-spacing:.04em;
  fill:var(--green-dark);
}
.cmp-endlbl{
  font-size:12px;
  font-weight:800;
}
.cmp-viz-foot{
  font-size:12px;
  color:var(--muted);
  margin:12px 0 4px;
  max-width:none;
}
@media(max-width:560px){
  .cmp-viz{padding:16px 14px 12px}
  .cmp-chart-svg{height:210px}
  .cmp-legend{gap:6px 14px;font-size:12.5px}
}


/* ---------------------------------------------------------------------------
   10. MOTION
   Everything below is optional decoration and is disabled wholesale for
   anyone who has asked for reduced motion.
   ------------------------------------------------------------------------ */

@media (prefers-reduced-motion: no-preference){

  /* Scroll reveal. The .rk-anim class is added by rk-ui.js, and .rk-rise is
     added per element by the same script, so if the script never runs nothing
     is ever hidden. Never move this starting state out of the .rk-anim scope. */
  .rk-anim .rk-rise{
    opacity:0;
    transform:translateY(16px);
    transition:opacity .55s cubic-bezier(.2,.85,.3,1),
               transform .55s cubic-bezier(.2,.85,.3,1);
  }
  .rk-anim .rk-rise.rk-in{
    opacity:1;
    transform:none;
  }

  /* The underline itself is declared in the navigation section so it survives
     reduced motion. Here it only gains the growth animation. */
  .rk-links a::after{
    transition:left .22s cubic-bezier(.2,.85,.3,1),
               right .22s cubic-bezier(.2,.85,.3,1);
  }

  /* Buttons acknowledge the press. */
  .reveal:active,
  .door:active,
  .fdtog:active,
  .seg button:active{transform:translateY(1px)}

  /* Tags lift very slightly, enough to read as tappable. */
  .tag{transition:transform .14s ease, filter .14s ease}
  .tag:hover{transform:translateY(-1px);filter:brightness(1.08)}

  /* A slow travelling highlight along the top edge of the result card. */
  @keyframes rkEdge{
    0%{transform:translateX(-60%)}
    100%{transform:translateX(60%)}
  }
  .headline::after{
    animation:rkEdge 7s ease-in-out infinite alternate;
  }

  /* Cards fade up as the page settles. Above the fold only, so nothing
     depends on scroll position or JavaScript. */
  @keyframes rkRise{
    from{opacity:0;transform:translateY(10px)}
    to{opacity:1;transform:none}
  }
  .headline{animation:rkRise .5s cubic-bezier(.2,.85,.3,1) both}
  #topperf{animation:rkRise .5s cubic-bezier(.2,.85,.3,1) .08s both}

  /* A single slow sweep of light across the result number after it lands.
     Runs twice, then stops. */
  @keyframes rkSheen{
    from{background-position:-140% 0}
    to{background-position:240% 0}
  }
  .headline .hs-main b{
    background-image:linear-gradient(100deg,
      currentColor 0%, currentColor 38%,
      color-mix(in srgb, currentColor 55%, #FFFFFF) 50%,
      currentColor 62%, currentColor 100%);
    background-size:220% 100%;
    -webkit-background-clip:text;
    background-clip:text;
    animation:rkSheen 2.6s ease-in-out 1.1s 2;
  }

  .panel,.bcard{transition:box-shadow .18s ease, border-color .18s ease}
}

@media (prefers-reduced-motion: reduce){
  .headline,#topperf{animation:none}
  .headline .hs-main b{animation:none;background-image:none}
  .headline::after{animation:none}
  .themetog:hover{transform:none}
  /* Belt and braces: rk-ui.js already declines to run under reduced motion,
     but if either class is ever applied the content must still be visible. */
  .rk-anim .rk-rise{opacity:1;transform:none;transition:none}
}


.cht-nums{margin-top:10px;font-size:13px}
.cht-nums summary{
  cursor:pointer;font-weight:600;color:var(--green-dark);
  min-height:44px;display:flex;align-items:center;list-style:none;
}
.cht-nums summary::-webkit-details-marker{display:none}
.cht-nums-wrap{overflow:auto;max-height:280px;margin-top:8px;-webkit-overflow-scrolling:touch}
.cht-nums table{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums}
.cht-nums caption{text-align:left;font-weight:600;margin-bottom:6px;color:var(--muted)}
.cht-nums th,.cht-nums td{padding:6px 8px;text-align:right;border-bottom:1px solid var(--border, var(--line, #E5E7EB));white-space:nowrap}
.cht-nums th:first-child,.cht-nums td:first-child{text-align:left}
.fp-spark,.navchart,.hs-spark .spark,.sparkwrap .spark{color:var(--green-dark)}
.navchart{color:var(--green-dark)}

.rk-menu-btn{
  display:none;border:0;background:transparent;cursor:pointer;
  width:44px;height:44px;padding:0;border-radius:var(--r-sm);
  color:var(--text, var(--ink, #1A1F2C));align-items:center;justify-content:center;
}
.rk-menu-btn:hover{background:rgba(46,204,113,.12)}
.rk-menu-btn svg{width:22px;height:22px}
.rk-menu{
  position:fixed;left:0;right:0;top:var(--rk-chrome,56px);z-index:80;
  background:var(--card);border-bottom:1px solid var(--border, var(--line, #E5E7EB));
  box-shadow:var(--el-2);padding:8px 12px 16px;
  max-height:calc(100dvh - var(--rk-chrome,56px));overflow:auto;
}
.rk-menu a{
  display:flex;align-items:center;min-height:44px;padding:0 12px;
  font-weight:700;color:var(--text, var(--ink, #1A1F2C));text-decoration:none;border-radius:var(--r-sm);
}
.rk-menu a:hover,.rk-menu a.active{background:rgba(46,204,113,.10);color:var(--green-dark)}
.rk-nav-end{display:flex;align-items:center;gap:2px;flex:none}
@media(max-width:900px){
  .rk-links-wide{display:none}
  .rk-menu-btn{display:inline-flex}
}
@media(min-width:901px){
  .rk-menu{display:none}
}
body.rk-menu-open{overflow:hidden}



@media print{
  .rk-nav,.qbar,.doors,.themetog,.rk-foot,#beta-notice,.rk-menu-btn,.rk-menu{display:none !important}
  .panel,.bcard,.headline{
    box-shadow:none;
    border:1px solid #CBD5E1;
    background:#fff;
    break-inside:avoid;
  }
  .rk-fold::before{display:none}
  .wrap{max-width:none;padding:0}
}

/* ---------------------------------------------------------------------------
   BLOG
   Pages are built on the stocks/versus shell, which declares --line and --ink
   rather than --border and --text, so every colour here uses the same fallback
   chain documented at the top of this file. Reading width is capped for prose
   only: tables and the FAQ run full width, because a fund table squeezed into
   a paragraph measure is unreadable on a phone.
--------------------------------------------------------------------------- */
.bl-post,.bl-index{max-width:none}
.bl-post>p,.bl-post>ul,.bl-post>h2,.bl-post>h3,.bl-standfirst{max-width:68ch}
.bl-crumb{font-size:13px;margin:0 0 6px}
.bl-crumb a{color:var(--green,#157A43);text-decoration:none;font-weight:700}
.bl-crumb a:hover{text-decoration:underline}
.bl-post h1{font-size:clamp(25px,5.2vw,40px);line-height:1.18;margin:0 0 10px;letter-spacing:-.02em}
.bl-meta{font-size:13px;color:var(--muted,#5b6b61);margin:0 0 16px}
.bl-meta span{opacity:.5;margin:0 7px}
.bl-standfirst{font-size:clamp(16px,2.4vw,19px);line-height:1.6;font-weight:500;
  color:var(--muted,#5b6b61);margin:0 0 22px}
.bl-post h2{font-size:clamp(19px,3.4vw,26px);line-height:1.3;margin:34px 0 12px;letter-spacing:-.01em}
.bl-post h3{font-size:clamp(16px,2.6vw,20px);margin:24px 0 8px}
.bl-post p{line-height:1.68;margin:0 0 15px}
.bl-post li{line-height:1.62;margin:0 0 7px}

/* The one sentence a skimmer should not miss. Also the sentence most likely to
   be lifted verbatim by an AI answer, so it is marked up as a distinct block. */
.bl-key{border-left:3px solid var(--green,#157A43);
  background:color-mix(in srgb, var(--green,#157A43) 7%, transparent);
  padding:13px 16px;border-radius:0 12px 12px 0;font-size:15.5px;font-weight:600;margin:20px 0}

.bl-live{font-size:13.5px;line-height:1.55;padding:11px 14px;border-radius:14px;
  border:1px solid color-mix(in srgb, var(--accent-4) 40%, transparent);
  background:color-mix(in srgb, var(--accent-4) 11%, transparent);
  color:var(--accent-4);margin:0 0 22px}

.bl-tablewrap{overflow-x:auto;margin:20px 0;-webkit-overflow-scrolling:touch}
.bl-table{width:100%;border-collapse:collapse;font-size:14px;min-width:440px}
.bl-table caption{caption-side:top;text-align:left;font-size:13px;line-height:1.5;
  color:var(--muted,#5b6b61);padding:0 0 10px}
.bl-table th,.bl-table td{padding:9px 11px;text-align:left;
  border-bottom:1px solid var(--border, var(--line, #E5E7EB))}
.bl-table thead th{font-size:12px;text-transform:uppercase;letter-spacing:.04em;
  color:var(--muted,#5b6b61);border-bottom-width:2px}
.bl-table tbody tr:nth-child(even){background:color-mix(in srgb, var(--muted,#5b6b61) 5%, transparent)}
.bl-table td a{color:var(--text, var(--ink, #1A1F2C));text-decoration:none;font-weight:600}
.bl-table td a:hover{color:var(--green,#157A43);text-decoration:underline}
.bl-num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.bl-table .bl-num{text-align:right}

.bl-faq{margin:36px 0 0}
.bl-faq h2{margin-top:0}
.bl-q{border:1px solid var(--border, var(--line, #E5E7EB));border-radius:14px;
  margin:0 0 9px;background:var(--card,#fff);overflow:hidden}
.bl-q summary{cursor:pointer;padding:14px 16px;font-weight:650;font-size:15px;
  list-style:none;min-height:44px;display:flex;align-items:center;gap:10px}
.bl-q summary::-webkit-details-marker{display:none}
.bl-q summary::after{content:"+";margin-left:auto;font-weight:700;font-size:19px;
  color:var(--green,#157A43);line-height:1}
.bl-q[open] summary::after{content:"\2212"}
.bl-q summary:hover{background:color-mix(in srgb, var(--green,#157A43) 5%, transparent)}
.bl-a{padding:0 16px 15px}
.bl-a p{margin:0;line-height:1.65;color:var(--muted,#5b6b61)}

.bl-cta{margin:34px 0 0}
.bl-btn{display:inline-block;padding:14px 24px;border-radius:999px;font-weight:750;
  text-decoration:none;color:#fff;background:linear-gradient(135deg,#157A43,#0F5F34);
  box-shadow:0 6px 18px rgba(21,122,67,.28);min-height:44px}
.bl-btn:hover{transform:translateY(-1px);box-shadow:0 9px 24px rgba(21,122,67,.34)}

.bl-cards{list-style:none;padding:0;margin:26px 0 0;display:grid;gap:14px;
  grid-template-columns:repeat(auto-fill,minmax(290px,1fr))}
.bl-card{margin:0}
.bl-card a{display:block;height:100%;padding:20px;border-radius:18px;text-decoration:none;
  border:1px solid var(--border, var(--line, #E5E7EB));background:var(--card,#fff);
  color:inherit;transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease}
.bl-card a:hover{transform:translateY(-2px);border-color:var(--green,#157A43);
  box-shadow:0 10px 26px rgba(0,0,0,.09)}
.bl-card h2{font-size:18px;line-height:1.32;margin:0 0 8px;letter-spacing:-.01em}
.bl-card p{font-size:14px;line-height:1.55;color:var(--muted,#5b6b61);margin:0 0 12px}
.bl-cardmeta{font-size:12px;color:var(--muted,#5b6b61);margin:0}
.bl-tag{display:inline-block;margin-left:7px;padding:2px 9px;border-radius:999px;
  font-size:11px;font-weight:750;color:var(--green,#157A43);
  background:color-mix(in srgb, var(--green,#157A43) 12%, transparent)}

@media (max-width:560px){
  .bl-table{font-size:13px;min-width:400px}
  .bl-table th,.bl-table td{padding:8px 9px}
  .bl-cards{grid-template-columns:1fr}
  .bl-btn{display:block;text-align:center}
}
@media (prefers-reduced-motion:reduce){
  .bl-card a:hover,.bl-btn:hover{transform:none}
}

/* ---------------------------------------------------------------------------
   BLOG CHARTS

   HTML, not SVG. The SVG version sized text and rows in viewBox units on a
   100-wide box, so at the real ~820px render every unit became 8.2px: a 34px
   font and a 246px row. Long fund names anchored inside a fixed gutter also ran
   off the left edge. None of that can happen here: sizes are real pixels at the
   same scale as the surrounding text, and a long label truncates instead of
   escaping its box.

   Grid columns: label | track | value. The track takes the remaining space, so
   the chart fits any width without measuring anything.
--------------------------------------------------------------------------- */
.bl-chart{margin:22px 0;padding:0;max-width:820px}
.bl-chartrows{display:flex;flex-direction:column;gap:9px}

.bl-crow{
  display:grid;
  /* 170px fits the longest label actually in the data ("VIPB Fixed Income
     Fund", 22 characters) without clipping, while still leaving the track the
     majority of the row. Anything longer truncates with an ellipsis and keeps
     its full name in the title attribute. */
  grid-template-columns:minmax(0,170px) 1fr minmax(0,auto);
  align-items:center;gap:12px;
}
.bl-clabel{
  font-size:13.5px;font-weight:650;line-height:1.3;
  color:var(--text, var(--ink, #1A1F2C));
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.bl-ctrack{position:relative;height:12px;border-radius:999px;
  background:color-mix(in srgb, var(--muted,#5b6b61) 13%, transparent)}
.bl-cbar{position:absolute;top:0;height:12px;border-radius:999px;display:block}
.bl-cval{font-size:13.5px;font-weight:750;font-variant-numeric:tabular-nums;
  white-space:nowrap;text-align:right;color:var(--muted,#5b6b61)}
.bl-chart figcaption{font-size:13px;line-height:1.5;margin-top:12px;
  color:var(--muted,#5b6b61)}

/* Light theme, matching the fund-type palette used on the homepage. */
.bc-growth{background:#059669}
.bc-balanced{background:#D97706}
.bc-income{background:#0284C7}
.bc-shariah{background:#4F46E5}
.bc-neutral{background:#64748B}
.bc-pos{background:#059669}
.bc-neg{background:#DC2626}

/* Dark theme: brighter, less saturated, mirroring the ty-* dark variants. */
[data-theme="dark"] .bc-growth{background:#34D399}
[data-theme="dark"] .bc-balanced{background:#FBBF24}
[data-theme="dark"] .bc-income{background:#38BDF8}
[data-theme="dark"] .bc-shariah{background:#818CF8}
[data-theme="dark"] .bc-neutral{background:#94A3B8}
[data-theme="dark"] .bc-pos{background:#34D399}
[data-theme="dark"] .bc-neg{background:#F87171}

/* Below 560px a 150px label gutter leaves almost nothing for the bar, so the
   label moves above its own full-width row and the value sits with it. */
@media (max-width:560px){
  .bl-crow{grid-template-columns:1fr auto;gap:4px 10px}
  .bl-clabel{grid-column:1;font-size:13px;white-space:normal}
  .bl-cval{grid-column:2;font-size:13px}
  .bl-ctrack{grid-column:1 / -1;height:10px}
  .bl-cbar{height:10px}
  .bl-chartrows{gap:14px}
}

/* The entrance animation NEVER touches width or scale.

   Two earlier attempts got this wrong. "animation: ... both" with scaleX(0)
   strands every bar invisible if the animation never runs. Dropping fill-mode
   fixed that case but not the real one: an animation can be applied and then
   STALL. Chrome pauses the animation timeline in a background tab, so a bar sat
   at scaleX(0) with playState "running" and currentTime 0, rendering at zero
   width. Headless renderers can capture the same frame.

   So the animated properties are opacity and a small horizontal nudge, and the
   opacity floor is 0.35 rather than 0. Stalled at frame zero, a bar is still
   full width, still the right colour, still readable. The animation can only
   ever make it look better, never hide it. On a page whose entire purpose is
   showing figures, that trade is not close. */
@media (prefers-reduced-motion:no-preference){
  .bl-cbar{animation:bcGrow .55s cubic-bezier(.22,1,.36,1) both}
  @keyframes bcGrow{
    from{opacity:.35;transform:translateX(-6px)}
    to{opacity:1;transform:none}
  }
}

/* ---------------------------------------------------------------------------
   BLOG TABLE WIDTH + BAR COLUMN

   Tables were stretching to the full page width while the prose beside them is
   capped at 68ch. On a wide desktop that left a two-column table with the name
   at the far left and the number at the far right, separated by a river of
   empty space. Capping the wrapper keeps a table near the measure of the text
   it belongs to, which is where the eye expects it.

   For the most-held table the middle column carries a proportional bar, so the
   width becomes information rather than a gap. The bar is decorative: the count
   is still in its own cell and read out normally, and the column header is
   sr-only rather than empty so the table has no unlabelled column.
--------------------------------------------------------------------------- */
/* .sr-only is declared in index.html but NOT in the stocks/versus/blog shell,
   where the only rule mentioning it is scoped to .rk-fold. Without this, the
   bar column's screen-reader-only header rendered as visible text in the table
   head. Identical to index.html's declaration, so pages that already have it
   are unaffected. */
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

.bl-tablewrap{max-width:820px}
.bl-chart{max-width:820px}

.bl-table-bars td:first-child{width:1%;white-space:nowrap;padding-right:16px}
.bl-table-bars .bl-barcell{width:auto;padding:9px 0}
.bl-table-bars .bl-num{width:1%;white-space:nowrap;padding-left:16px}

.bl-minibar{
  display:block;height:9px;border-radius:999px;min-width:3px;
  background:linear-gradient(90deg,
    color-mix(in srgb, var(--green,#157A43) 55%, transparent),
    var(--green,#157A43));
}
[data-theme="dark"] .bl-minibar{
  background:linear-gradient(90deg,
    color-mix(in srgb, #34D399 45%, transparent), #34D399);
}

/* Below 560px the bar column is the first thing to sacrifice: a name and its
   number matter more than a decorative bar on a 390px screen, and dropping it
   lets the table fit without sideways scrolling. */
@media (max-width:560px){
  .bl-table-bars{min-width:0}
  .bl-table-bars .bl-barcell{display:none}
  .bl-table-bars td:first-child{white-space:normal}
}
