/* RI Membership — member dashboard, styled to the approved "Opsi B" spec
   (Spesifikasi Dashboard Member, section 3).

   The first four tokens keep the names elementor-widgets.php writes onto a
   widget wrapper (Style → Card Style), so per-instance overrides still work.
   Everything below them is the design system the spec fixes: warm cream page,
   off-white cards on sand borders, Lora for anything title-shaped, Nunito Sans
   for body. Fonts are scoped to .ri-* components on purpose — ri-theme.css sets
   Raleway site-wide and this spec only governs the dashboard. */
:root {
	--ri-accent: #2e6b4f;
	--ri-bg:     #fffdf8;
	--ri-line:   #e7e0d2;
	--ri-radius: 16px;

	--ri-ink:        #241f18;  /* titles */
	--ri-body:       #5b5548;  /* body copy */
	--ri-muted:      #8a8272;  /* captions, "Baru" */
	--ri-page:       #f4efe4;
	--ri-green-deep: #24523d;  /* status banner, normal */
	--ri-green-pale: #cfe3d7;  /* text on the green banner */
	--ri-terra:      #8f4225;  /* status banner, <= 14 days */
	--ri-terra-pale: #fbe9dc;
	--ri-terra-line: #efd2bc;
	--ri-gold:       #f2c14e;
	--ri-gold-ink:   #3a2c07;
	--ri-progress:   #b5532f;  /* "Sedang berjalan" */

	--ri-accent-soft: #e4efe8;  /* badge fill */
	--ri-shade:       #efe9dc;  /* thumbnail placeholder, muted chips */
	--ri-shadow:      rgba(36,31,24,.08);

	--ri-serif: "Lora", Georgia, serif;
	--ri-sans:  "Nunito Sans", "Raleway", -apple-system, BlinkMacSystemFont, sans-serif;
}

.ri-dashboard { max-width:1100px; margin:0 auto; font-family:var(--ri-sans); color:var(--ri-body); }
.ri-dashboard section { margin:28px 0; }

/* ----------------------------------------------------------------- layout -- */
/* Two columns: a 280px sidebar that sticks, and a main column that grows.
   flex-wrap (not a media query) does the responsive work — below ~600px of
   main-column room the sidebar wraps ABOVE the content rather than being
   hidden, which is what the spec asks for. */
.ri-dash-layout { display:flex; flex-wrap:wrap; gap:24px; align-items:flex-start; }
.ri-dash-side { flex:0 0 280px; min-width:260px; display:flex; flex-direction:column; gap:16px; position:sticky; top:20px; }
.ri-dash-main { flex:1; min-width:340px; }
.ri-dash-main section { margin:0 0 24px; }

/* Doubled class selectors below are deliberate, not a typo.
   Elementor's Global Kit emits `.elementor-kit-NNNN h2 {…}` — specificity
   (0,1,1) — which beats a single class like `.ri-welcome` (0,1,0). The result
   was that our tokens were being set correctly on the wrapper and then losing
   the cascade, so the Style tab appeared to do nothing at all. Repeating the
   class lifts us to (0,2,0) without reaching for !important, which would take
   the styling away from the team entirely. */
.ri-welcome.ri-welcome { font-family:var(--ri-serif); font-weight:700; font-size:clamp(20px,3vw,26px); color:var(--ri-ink); margin:0 0 20px; }
.ri-section-title { font-weight:800; color:var(--ri-ink); font-size:15px; margin:0 0 12px; font-family:var(--ri-sans); }

/* A rail, not a grid: "Lanjutkan Belajar" is a short ordered queue, so it reads
   left-to-right and scrolls rather than reflowing into rows. */
.ri-rail { display:flex; gap:16px; overflow-x:auto; padding-bottom:4px; }
.ri-rail .ri-card { flex:0 0 200px; }

.ri-contact {
	display:block; background:var(--ri-bg); border:1px solid var(--ri-line); border-radius:var(--ri-radius);
	padding:14px 18px; color:var(--ri-accent); font-weight:700; font-size:13px; text-decoration:none; text-align:center;
}
.ri-contact:hover { background:var(--ri-accent); color:var(--ri-bg); }

.ri-panel[hidden] { display:none; }

/* The sidebar can outgrow the viewport once a member has several cards; drop
   the stickiness rather than trapping the bottom of it off-screen. */
@media (max-height:760px), (max-width:900px) { .ri-dash-side { position:static; } }
.ri-dashboard.ri-dashboard h2,
.ri-dashboard.ri-dashboard h3 { font-family:var(--ri-serif); color:var(--ri-ink); }
.ri-dashboard.ri-dashboard h2 { margin:0 0 6px; }
.ri-dashboard.ri-dashboard h3 { font-size:1.1rem; margin:0 0 12px; }

.ri-dash-head { padding-bottom:16px; border-bottom:1px solid var(--ri-line); }
.ri-account { display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-top:8px; }
.ri-badge { display:inline-block; font-size:.8rem; padding:3px 10px; border-radius:100px; background:var(--ri-accent-soft); color:var(--ri-accent); }
.ri-badge-muted { background:var(--ri-shade); color:var(--ri-muted); }
.ri-link { font-size:.85rem; color:var(--ri-accent); }
/* Own line under the badge row: flex-basis forces the wrap, order keeps it below
   the "Ubah password" link even though the markup emits it first. */
.ri-account-cta { flex-basis:100%; order:9; margin:4px 0 0; font-size:.88rem; color:var(--ri-body); }

/* ------------------------------------------------------------ profile card - */

.ri-profile {
	background:var(--ri-bg); border:1px solid var(--ri-line); border-radius:var(--ri-radius);
	padding:20px; text-align:center; font-family:var(--ri-sans);
}
.ri-profile-avatar { width:80px; height:80px; border-radius:50%; object-fit:cover; margin:0 auto 12px; display:block; }
.ri-profile-name { font-family:var(--ri-serif); font-weight:700; font-size:18px; color:var(--ri-ink); }
.ri-profile-tier { font-size:12px; color:var(--ri-accent); text-transform:uppercase; letter-spacing:.05em; margin-top:4px; font-weight:700; }

/* Status banner. Green while there is comfortable time left, terracotta inside
   the 14-day window — the colour IS the warning, so it carries the urgency
   even before the text is read. */
.ri-status { margin-top:14px; border-radius:12px; padding:12px 14px; background:var(--ri-green-deep); }
.ri-status-text { font-size:12px; color:var(--ri-green-pale); }
.ri-status--urgent { background:var(--ri-terra); }
.ri-status--urgent .ri-status-text { color:var(--ri-terra-pale); }

/* The account page reuses the green plate but stacks four lines on it instead
   of one, so it gets its own modifier and its own rhythm. Without this the
   spans are plain inline text: no gap, and inheriting near-black body colour
   onto dark green — "Paket aktifCoaching LanjutanBerlaku selamanya", unreadable. */
.ri-status--akun { display:flex; flex-direction:column; align-items:flex-start; gap:6px; }
.ri-status--akun .ri-status-label {
	font-size:12px; letter-spacing:.04em; text-transform:uppercase; color:var(--ri-green-pale);
}
.ri-status--akun strong {
	font-family:var(--ri-serif,Lora),Georgia,serif; font-size:20px; line-height:1.25; color:var(--ri-gold);
}
.ri-status--akun .ri-status-sub { font-size:13px; color:var(--ri-green-pale); }
.ri-status--akun .ri-status-cta {
	margin-top:4px; padding:8px 14px; border-radius:999px; text-decoration:none;
	background:var(--ri-gold); color:var(--ri-gold-ink); font-size:13px; font-weight:600;
}
.ri-status--akun .ri-status-cta:hover { filter:brightness(1.06); }

/* Gold on terracotta is muddy, so the urgent plate swaps to cream throughout
   and the button inverts rather than staying gold. */
.ri-status--urgent.ri-status--akun strong { color:#fff; }
.ri-status--urgent .ri-status-label,
.ri-status--urgent .ri-status-sub { color:var(--ri-terra-pale); }
.ri-status--urgent .ri-status-cta { background:var(--ri-terra-pale); color:var(--ri-terra); }
.ri-renew {
	display:block; margin-top:10px; width:100%; background:var(--ri-gold); color:var(--ri-gold-ink);
	border:none; border-radius:9px; padding:9px; font-weight:700; font-size:13px; cursor:pointer;
	font-family:inherit; text-align:center; text-decoration:none;
}
.ri-renew:hover { filter:brightness(.96); color:var(--ri-gold-ink); }
/* Not a button on purpose: outside the renewal window an upgrade is an offer,
   not a task, and a second gold button would compete with the real CTA. */
.ri-upgrade { display:block; margin-top:10px; color:var(--ri-accent); font-size:12px; font-weight:700; text-decoration:none; }

/* ------------------------------------------------------------- side cards -- */

.ri-sidecard { background:var(--ri-bg); border:1px solid var(--ri-line); border-radius:var(--ri-radius); padding:16px 18px; }
.ri-sidecard-label { color:var(--ri-accent); font-size:11px; text-transform:uppercase; letter-spacing:.05em; font-weight:700; margin-bottom:6px; }
/* [ri_announcements] draws its own card, which nested inside .ri-sidecard gave
   a bordered box inside a bordered box. In the sidebar the sidecard IS the
   card, so the inner chrome is stripped and only the text remains. */
.ri-sidecard .ri-announcements { margin:0; gap:10px; }
.ri-sidecard .ri-announcement { background:none; border:0; border-radius:0; padding:0; }
.ri-sidecard .ri-announcement.ri-announcement h4 { font-family:var(--ri-sans); font-size:13px; font-weight:700; color:var(--ri-ink); margin:0; }

/* ------------------------------------------------------------------ cards -- */

/* auto-FIT, not auto-fill: with auto-fill a member holding two materials gets
   two cards plus three empty column tracks stretched across the row. */
.ri-grid { display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:16px; }
.ri-card {
	display:flex; flex-direction:column; border:1px solid var(--ri-line); border-radius:14px;
	overflow:hidden; text-decoration:none; color:inherit; background:var(--ri-bg);
	transition:box-shadow .15s, transform .15s;
}
.ri-card:hover { box-shadow:0 6px 20px var(--ri-shadow); transform:translateY(-2px); }
.ri-card.is-done { opacity:.7; }
/* aspect-ratio, not a fixed height: thumbnails are authored 16:9 and a fixed
   130px crop was cutting the bottom off every one of them. */
.ri-card-img { display:block; aspect-ratio:16/9; background-size:cover; background-position:center; background-color:var(--ri-shade); }
/* A material with no featured image still reserves the frame, so one missing
   picture doesn't shorten that card and knock the whole row out of alignment. */
.ri-card-img.is-empty { background-image:none; }

/* Read-state badge, top-right of the thumbnail. Never-opened renders nothing at
   all, so the grid stays quiet and only the pages you've touched are marked. */
.ri-card-img { position:relative; }
.ri-card-state {
	position:absolute; top:8px; right:8px; width:22px; height:22px; border-radius:50%;
	display:flex; align-items:center; justify-content:center;
	background:var(--ri-bg); box-shadow:0 1px 4px var(--ri-shadow);
}
.ri-card-state.is-done { background:var(--ri-accent); color:var(--ri-bg); }
.ri-card-state.is-read { background:var(--ri-bg); color:var(--ri-muted); }

/* --------------------------------------------------- done button on a materi */
/* Its own block at the foot of the page, not a control tucked into a card —
   finishing something is a decision you make where you finished it. */
.ri-material-done { margin:32px 0 8px; padding-top:24px; border-top:1px solid var(--ri-line); }
.ri-done-btn--page {
	align-self:auto; font-family:var(--ri-sans); font-size:14px; font-weight:700;
	padding:11px 22px; border-radius:10px;
	border:1px solid var(--ri-accent); background:var(--ri-accent); color:var(--ri-bg);
}
.ri-done-btn--page:hover { filter:brightness(.94); }
.ri-done-btn--page.is-done { background:transparent; color:var(--ri-accent); }
/* Explicit margins rather than a flex gap: the spec spaces the status label at
   6px and the rail's meta line at 3px, which one shared gap can't express. */
/* Spacing between the lines is `gap` and nothing else. It used to be three
   separate margin-tops on the children, which meant the Style tab's control —
   which sets gap — could only ever ADD to them: dragging to 0 changed nothing
   and there was no way to get tighter. One mechanism, so 0 really is flush. */
.ri-card-body { padding:14px; display:flex; flex-direction:column; }
/* Spacing rides on the adjacent sibling, not on `gap`. CSS forbids a negative
   gap, and 0 is not always tight enough once each line brings its own leading —
   a margin can go negative and pull the lines back together. */
.ri-card-body > * + * { margin-top:6px; }
.ri-card-title { font-family:var(--ri-serif); font-weight:700; font-size:14px; line-height:1.3; color:var(--ri-ink); }
.ri-card-status { font-size:12px; font-weight:700; margin-top:6px; }
.ri-card-status.is-done { color:var(--ri-accent); }
.ri-card-status.is-progress { color:var(--ri-progress); }
.ri-card-status.is-new { color:var(--ri-muted); }
.ri-card-meta { font-size:12px; color:var(--ri-muted); }

/* Rail cards are deliberately denser than grid cards and set their title in the
   sans face, not Lora — the mockup treats the rail as a queue you scan and the
   grid as a library you browse. */
/* No rail-specific padding: the Style tab offers one "jarak dalam kartu" and it
   should mean the same thing in both layouts. Two hidden values behind one
   control is how the last slider ended up unable to reach what it named. */
.ri-rail .ri-card-title { font-family:var(--ri-sans); font-size:13px; }

.ri-bar { display:block; height:7px; border-radius:100px; background:var(--ri-line); overflow:hidden; }
.ri-bar-fill { display:block; height:100%; background:var(--ri-accent); }
.ri-pct { font-size:.78rem; color:var(--ri-muted); }

.ri-done-btn, .ri-btn {
	align-self:flex-start; font:inherit; font-family:var(--ri-sans); font-size:.82rem; padding:6px 12px;
	border-radius:8px; border:1px solid var(--ri-line); background:transparent; color:var(--ri-accent);
	cursor:pointer; text-decoration:none;
}
.ri-done-btn:hover, .ri-btn:hover { background:var(--ri-accent); border-color:var(--ri-accent); color:var(--ri-bg); }

/* ------------------------------------------------------------------- tabs -- */

.ri-tabs { display:flex; gap:8px; overflow-x:auto; margin-bottom:20px; padding-bottom:4px; }
.ri-tab {
	flex:0 0 auto; padding:9px 16px; border-radius:20px; border:1px solid var(--ri-line);
	background:var(--ri-bg); color:var(--ri-body); font-size:13px; font-weight:700;
	font-family:var(--ri-sans); cursor:pointer; white-space:nowrap; text-decoration:none;
}
.ri-tab.is-active { background:var(--ri-accent); border-color:var(--ri-accent); color:var(--ri-bg); }
/* Locked tiers stay visible and legible — the tab strip is the upsell, so
   greying a tier out of existence would hide the thing we want them to want. */
.ri-tab.is-locked::after { content:" 🔒"; }

.ri-locked-banner {
	background:var(--ri-terra-pale); border:1px solid var(--ri-terra-line); border-radius:14px;
	padding:16px 20px; margin-bottom:16px; display:flex; flex-wrap:wrap; align-items:center;
	justify-content:space-between; gap:12px;
}
.ri-locked-banner p { margin:0; color:var(--ri-terra); font-size:14px; font-weight:700; }
.ri-locked-banner a { background:var(--ri-terra); color:var(--ri-bg); border-radius:10px; padding:9px 16px; font-size:13px; font-weight:700; text-decoration:none; }
.ri-grid.is-locked .ri-card { opacity:.55; }
/* A single locked card inside an otherwise-owned grid — the recommendations
   deliberately mix both, so the fade belongs on the card, not the container. */
.ri-card.is-locked { opacity:.55; }
.ri-card.is-locked .ri-card-lock { opacity:1; }

/* ----------------------------------------------------------------- ambient - */

.ri-highlight { background:var(--ri-bg); border:1px solid var(--ri-line); border-radius:var(--ri-radius); padding:18px 20px; }
.ri-empty { color:var(--ri-muted); font-style:italic; }

.ri-progress-summary { display:flex; flex-direction:column; gap:10px; }
.ri-progress-row { display:grid; grid-template-columns:1fr 120px 44px; align-items:center; gap:12px; font-size:.9rem; }

.ri-ambient { display:grid; grid-template-columns:1fr 1fr; gap:16px; margin-top:24px; }
/* The gold dot replaces the old left rule — same "this is a pull-quote" signal,
   but it reads as warmth rather than as a blockquote bar. */
.ri-inspirasi { background:var(--ri-bg); border:1px solid var(--ri-line); border-radius:var(--ri-radius); padding:18px; display:flex; gap:10px; }
.ri-inspirasi::before { content:""; width:6px; height:6px; border-radius:50%; background:var(--ri-gold); margin-top:7px; flex-shrink:0; }
.ri-inspirasi-text { font-family:var(--ri-serif); font-style:italic; font-size:14px; line-height:1.5; color:var(--ri-ink); }
.ri-inspirasi-attr { margin-top:6px; font-size:12px; color:var(--ri-muted); }

.ri-announcements { display:flex; flex-direction:column; gap:12px; margin:16px 0; }
.ri-announcement { background:var(--ri-bg); border:1px solid var(--ri-line); border-radius:var(--ri-radius); padding:16px 18px; }
.ri-announcement.ri-announcement h4 { margin:0 0 6px; font-family:var(--ri-serif); color:var(--ri-ink); }

.ri-locked { background:var(--ri-terra-pale); border:1px solid var(--ri-terra-line); padding:20px; border-radius:var(--ri-radius); }

@media (max-width:600px) { .ri-ambient, .ri-progress-row { grid-template-columns:1fr; } }

/* ============================================== spec v2: status, ribbon, topics */

/* Read status sits under the title on its own line — not on the thumbnail. All
   three states are labelled, "Belum dibaca" included, so a grid reads as a
   consistent column rather than badges appearing on some cards and not others. */
.ri-read { display:flex; align-items:center; gap:6px; font-size:12px; font-weight:700; }
.ri-read svg { flex-shrink:0; }
.ri-read.is-unread  { color:var(--ri-muted); }
.ri-read.is-reading { color:var(--ri-progress); }
.ri-read.is-done    { color:var(--ri-accent); }

/* Category line: green uppercase with a small gold dot, no pill background. */
.ri-card-cat {
	display:flex; align-items:center; gap:6px;
	font-size:11px; font-weight:700; letter-spacing:.05em;
	text-transform:uppercase; color:var(--ri-accent);
}
.ri-card-cat::before { content:""; width:5px; height:5px; border-radius:50%; background:var(--ri-gold); flex-shrink:0; }

/* "BARU" ribbon, corner of the thumbnail. Rotated rather than a straight tag so
   it reads as a flash on the image instead of another label competing with the
   status line below. */
.ri-card-img { overflow:hidden; }
.ri-ribbon {
	position:absolute; top:10px; right:-30px; transform:rotate(45deg);
	background:var(--ri-gold); color:var(--ri-gold-ink);
	font-size:9px; font-weight:800; letter-spacing:.08em;
	padding:3px 34px; text-align:center; pointer-events:none;
}
.ri-card-lock {
	position:absolute; top:8px; left:8px; width:22px; height:22px; border-radius:50%;
	display:flex; align-items:center; justify-content:center;
	background:var(--ri-terra-pale); color:var(--ri-terra);
}

/* ---- "Mau belajar apa hari ini?" ---- */
.ri-topics {
	background:var(--ri-bg); border:1px solid var(--ri-line); border-radius:var(--ri-radius);
	padding:28px 24px; text-align:center; margin:24px 0;
}
.ri-topics-head { display:flex; flex-direction:column; align-items:center; gap:4px; }
.ri-topics-icon {
	width:44px; height:44px; border-radius:50%; display:flex; align-items:center; justify-content:center;
	background:var(--ri-accent-soft); color:var(--ri-accent); margin-bottom:6px;
}
.ri-topics-title { font-family:var(--ri-serif); font-size:20px; font-weight:700; color:var(--ri-ink); margin:0; }
.ri-topics-sub { font-size:13px; color:var(--ri-muted); margin:0 0 4px; }
.ri-chips { display:flex; flex-wrap:wrap; justify-content:center; gap:8px; margin-top:16px; }
.ri-chip {
	font-family:var(--ri-sans); font-size:13px; font-weight:700; cursor:pointer;
	padding:9px 16px; border-radius:20px; white-space:nowrap;
	border:1px solid var(--ri-line); background:var(--ri-bg); color:var(--ri-body);
	transition:background .12s, color .12s, border-color .12s;
}
.ri-chip:hover { border-color:var(--ri-accent); color:var(--ri-accent); }
.ri-chip.is-on { background:var(--ri-accent); border-color:var(--ri-accent); color:var(--ri-bg); }
.ri-chip[aria-busy="true"] { opacity:.5; pointer-events:none; }
.ri-reco:empty { display:none; }
.ri-reco { margin-top:20px; }

/* Category tabs as underline, not pills (spec v2 §3 revision). The strip keeps a
   hairline under its full width so the active tab reads as sitting on a rule
   rather than floating. */
.ri-tabs { border-bottom:1px solid var(--ri-line); gap:22px; }
/* Type scale and padding taken from the design's own tab style: tight
   horizontal padding with the gap doing the spacing, so the underline sits
   under the word rather than under a wide invisible box. */
.ri-tab {
	border:0; border-bottom:2px solid transparent; border-radius:0;
	background:none; color:var(--ri-muted); font-size:14px; font-weight:800;
	padding:10px 2px 12px; margin-bottom:-1px;
}
.ri-tab:hover { color:var(--ri-body); }
.ri-tab.is-active { background:none; color:var(--ri-accent); border-bottom-color:var(--ri-accent); }

/* Event date on an announcement card — rendered from the field, so the title
   stays "Kelas Live" and the date can never disagree with the calendar. */
.ri-announce-when { font-size:12px; font-weight:700; color:var(--ri-accent); margin:2px 0 4px; }
.ri-announce-soon { color:var(--ri-progress); font-weight:700; }

/* Subtopic chips sit visually below their parents — smaller and lighter, so a
   two-tier row still reads as one control rather than twelve equal choices. */
.ri-chip.is-child { font-size:12px; padding:7px 14px; border-style:dashed; }
.ri-chip.is-child.is-on { border-style:solid; }
.ri-chips--drilldown { flex-direction:row; }

/* Chips without our heading — the page already has one, built in Elementor.
   Drops the card frame too, otherwise the chips arrive inside a second box
   sitting under the box the team just designed. */
.ri-topics.is-bare { background: none; border: 0; padding: 0; }
.ri-topics.is-bare .ri-chips { margin-top: 0; }

/* Membership panel: one plate per package the member holds. The green plate is
   reused rather than restyled, so a list of three reads as three of the same
   thing — but the stacking margin has to go, or each plate re-adds its own. */
.ri-paket-list { display:flex; flex-direction:column; align-items:stretch; gap:10px; }
.ri-paket-list .ri-status { margin-top:0; }
.ri-paket-label {
	font-size:12px; letter-spacing:.04em; text-transform:uppercase; color:var(--ri-muted);
}
.ri-paket-cta {
	align-self:flex-start; margin-top:2px; padding:9px 16px; border-radius:999px;
	background:var(--ri-gold); color:var(--ri-gold-ink);
	font-size:13px; font-weight:600; text-decoration:none;
}
.ri-paket-cta:hover { filter:brightness(1.06); }

/* Lapsed packages sit quietly below — present, clearly over, not competing
   with the live ones for attention. */
.ri-paket-past { margin-top:20px; }
.ri-paket-past h4 {
	margin:0 0 6px; font-size:12px; letter-spacing:.04em;
	text-transform:uppercase; color:var(--ri-muted);
}
.ri-paket-past .ri-rows strong { color:var(--ri-body); font-weight:600; }
.ri-paket-past .ri-rows small { color:var(--ri-muted); }
