/*
Theme Name:   AB Portfolio
Theme URI:    https://ankitaborawake.com
Description:  Custom child theme for ankitaborawake.com. Two colours, two
              typefaces, no page builder.
Author:       Ankita Borawake
Template:     generatepress
Version:      2.2.0
License:      GNU General Public License v2 or later
Text Domain:  ab-portfolio
*/

/* =========================================================================
   1. TOKENS
   Two colours. In dark mode they swap roles. --surface stays light in both,
   so the blue survives; --on-surface stays dark for the same reason.
   ====================================================================== */

:root {
	--bg:          #FFFDF9;   /* Lotion       */
	--ink:         #340F12;   /* Black Rooster */
	--surface:     #E4F0FA;   /* Cotton Boll  */
	--on-surface:  #340F12;   /* text sitting on --surface, both modes */

	/* Derived, never hand-picked */
	--rule:        color-mix(in srgb, var(--ink) 14%, transparent);
	--rule-strong: color-mix(in srgb, var(--ink) 28%, transparent);
	--ghost:       color-mix(in srgb, var(--ink) 8%,  transparent);

	/* Type */
	--font-display: "Instrument Serif", Georgia, "Times New Roman", serif;
	--font-body:    "Instrument Sans", system-ui, -apple-system, "Segoe UI", sans-serif;

	/* Spacing */
	--gutter:       clamp(1.25rem, 5vw, 4.5rem);
	--section-y:    clamp(5rem, 12vw, 11rem);
	--measure:      62ch;

	/* Motion */
	--ease:         cubic-bezier(0.22, 0.61, 0.36, 1);
	--dur:          420ms;
}

[data-theme="dark"] {
	--bg:  #340F12;
	--ink: #FFFDF9;
}

/* =========================================================================
   2. BASE
   ====================================================================== */

*,
*::before,
*::after { box-sizing: border-box; }

html {
	scroll-behavior: smooth;
	/* Stops the sticky nav covering a heading when you jump to a section */
	scroll-padding-top: 6rem;
	-webkit-text-size-adjust: 100%;
}

body {
	margin: 0;
	background: var(--bg);
	color: var(--ink);
	font-family: var(--font-body);
	font-size: 1.0625rem;
	line-height: 1.65;
	font-synthesis-weight: none;
	-webkit-font-smoothing: antialiased;
	transition: background-color var(--dur) var(--ease),
	            color var(--dur) var(--ease);
}

img,
video { max-width: 100%; height: auto; display: block; }

h1, h2, h3, h4 {
	font-family: var(--font-display);
	font-weight: 400;
	line-height: 1.02;
	letter-spacing: -0.015em;
	text-wrap: balance;
	margin: 0;
}

p { margin: 0 0 1.15em; max-width: var(--measure); }
p:last-child { margin-bottom: 0; }

/* Links carry an underline, not a colour. Colour alone would fail WCAG 1.4.1
   and there is no accent token to spare. :visited is stated explicitly
   because the parent theme colours visited links. */
a,
a:visited {
	color: inherit;
	text-decoration: underline;
	text-decoration-thickness: 1px;
	text-underline-offset: 0.22em;
	transition: text-decoration-thickness 160ms var(--ease);
}
a:hover { text-decoration-thickness: 2px; }

:focus-visible {
	outline: 2px solid var(--ink);
	outline-offset: 3px;
	border-radius: 2px;
}

::selection { background: var(--ink); color: var(--bg); }

/* =========================================================================
   3. UTILITIES
   ====================================================================== */

.wrap {
	width: 100%;
	max-width: 1440px;
	margin-inline: auto;
	padding-inline: var(--gutter);
}

.sr-only {
	position: absolute; width: 1px; height: 1px;
	padding: 0; margin: -1px; overflow: hidden;
	clip-path: inset(50%); white-space: nowrap; border: 0;
}

.skip-link {
	position: absolute; top: 0; left: 50%;
	transform: translate(-50%, -110%);
	z-index: 200;
	background: var(--ink); color: var(--bg);
	padding: 0.75rem 1.25rem;
	text-decoration: none;
	font-size: 0.875rem;
}
.skip-link:focus { transform: translate(-50%, 0); }

.eyebrow {
	font-family: var(--font-body);
	font-size: 0.75rem;
	font-weight: 500;
	letter-spacing: 0.14em;
	text-transform: uppercase;
	opacity: 0.6;
	margin: 0;
}

.lede { font-size: clamp(1.0625rem, 1.6vw, 1.3125rem); line-height: 1.55; }

/* =========================================================================
   4. HEADER / NAV
   ====================================================================== */

.site-header {
	position: sticky; top: 0; z-index: 100;
	background: color-mix(in srgb, var(--bg) 86%, transparent);
	backdrop-filter: blur(12px);
	border-bottom: 1px solid var(--rule);
}

.site-header__inner {
	display: flex; align-items: center; justify-content: space-between;
	gap: 1.5rem;
	min-height: 4.5rem;
}

.brand {
	font-family: var(--font-display);
	font-size: 1.375rem;
	letter-spacing: -0.01em;
	text-decoration: none;
}

/* ---- Nav -------------------------------------------------------------
   EDIT HERE:
     .nav__list gap  -> space between nav items
     .nav__link font-size -> nav text size
     .nav__link opacity   -> resting dimness (hover goes to 1)
     .brand font-size     -> your name, top left                       */

.nav { display: flex; align-items: center; gap: clamp(1rem, 2.4vw, 2.25rem); }

.nav__list {
	display: flex; align-items: center;
	gap: clamp(1rem, 2.4vw, 2.25rem);
	list-style: none; margin: 0; padding: 0;
}

.nav__link,
.nav__link:visited {
	/* :visited is spelled out because GeneratePress colours visited links, and
	   an anchor you have clicked counts as visited — which turned one nav item
	   nearly invisible. */
	color: inherit;
	display: inline-flex; align-items: baseline; gap: 0.45rem;
	font-size: 0.9375rem;
	text-decoration: none;
	padding-block: 0.35rem;
	opacity: 0.72;
	transition: opacity 180ms var(--ease);
}

.nav__link:hover,
.nav__link:focus-visible,
.nav__link[aria-current="true"] { opacity: 1; }


/* ---- Circular icon buttons ------------------------------------------
   Shared by the theme toggle and the carousel arrows. GeneratePress styles
   bare <button> elements with its own padding, font-size and line-height;
   all three have to be reset or the icon is pushed off-centre or clipped.
   Sized at 2.75rem (44px) to meet the minimum touch target.            */

.theme-toggle,
.quotes-nav__btn {
	box-sizing: border-box;
	width: 2.75rem;
	height: 2.75rem;
	padding: 0;
	margin: 0;
	line-height: 1;
	font-size: 0;
	display: flex;
	align-items: center;
	justify-content: center;
	background: none;
	border: 1px solid var(--rule-strong);
	border-radius: 50%;
	color: inherit;
	cursor: pointer;
	transition: background-color 200ms var(--ease),
	            color 200ms var(--ease),
	            border-color 200ms var(--ease),
	            opacity 200ms var(--ease);
}

/* Inline SVGs sit on the text baseline, which leaves descender space below
   and pushes the glyph visually high inside the circle. */
.theme-toggle svg,
.quotes-nav__btn svg {
	display: block;
	width: 1.0625rem;
	height: 1.0625rem;
	flex: none;
}

.theme-toggle:hover,
.quotes-nav__btn:hover:not(:disabled) {
	background: var(--ink);
	color: var(--bg);
	border-color: var(--ink);
}

.quotes-nav__btn:disabled {
	opacity: 0.28;
	cursor: default;
}

.theme-toggle .icon-sun  { display: none; }
[data-theme="dark"] .theme-toggle .icon-sun  { display: block; }
[data-theme="dark"] .theme-toggle .icon-moon { display: none; }

@media (max-width: 800px) {
	.nav__list { display: none; }
}

/* =========================================================================
   5. SECTIONS + THE GHOST NUMERAL
   ====================================================================== */

/* No divider rules between sections — the vertical rhythm from --section-y
   does the separating. Rules made the page read like slides. */
.section {
	position: relative;
	padding-block: var(--section-y);

	/* An anchor aligns a section's top EDGE, which sits a full --section-y
	   above its heading — so you land on empty space with the section's
	   bottom pushed off-screen. Cancelling that padding here means the
	   heading lands just under the sticky header instead. The negative value
	   is deliberate; scroll-padding-top on <html> supplies the clearance. */
	scroll-margin-top: calc(var(--section-y) * -1);
}

.section__head {
	display: flex; align-items: baseline; gap: 1rem;
	margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}

.section__title { font-size: clamp(2rem, 4.6vw, 3.75rem); }

.section > .wrap { position: relative; z-index: 1; }

/* =========================================================================
   6. HERO
   ====================================================================== */

.hero { padding-block: clamp(5rem, 16vh, 10rem) var(--section-y); }

.hero__statement {
	font-family: var(--font-display);
	font-size: clamp(2.125rem, 5.4vw, 4.75rem);
	line-height: 1.06;
	letter-spacing: -0.022em;
	max-width: 24ch;
	margin: 1.75rem 0 0;
	text-wrap: pretty;
}

/* The one clause nobody else can claim. Italic, not colour — it still reads
   as emphasis in dark mode, in print, and to a screen reader via <em>. */
.hero__statement em {
	font-style: italic;
}

.hero__meta {
	display: flex; flex-wrap: wrap; gap: 0.6rem 1.75rem;
	margin-top: clamp(2.5rem, 5vw, 4rem);
	padding-top: 1.5rem;
	border-top: 1px solid var(--rule);
	font-size: 0.9375rem;
}
.hero__meta span { opacity: 0.68; }

/* =========================================================================
   7. WORK GRID
   ====================================================================== */

.work-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(26rem, 100%), 1fr));
	gap: clamp(2rem, 4vw, 3.5rem);
	list-style: none; margin: 0; padding: 0;
}

.card { position: relative; }

.card__link {
	display: block;
	text-decoration: none;
	color: inherit;
}
/* One big hit area, but only the title is announced as the link text. */
.card__link::after {
	content: ""; position: absolute; inset: 0;
}

.card__media {
	position: relative;
	aspect-ratio: 4 / 3;
	overflow: hidden;
	background: var(--surface);
	border-radius: 3px;
}
.card__media img {
	width: 100%; height: 100%; object-fit: cover;
	transition: transform 620ms var(--ease);
}
.card:hover .card__media img { transform: scale(1.035); }

.card__index {
	position: absolute; top: 0.9rem; left: 0.9rem;
	z-index: 2;
	font-size: 0.75rem;
	letter-spacing: 0.08em;
	font-variant-numeric: tabular-nums;
	background: var(--bg);
	color: var(--ink);
	padding: 0.3rem 0.55rem;
	border-radius: 2px;
}

.card__body {
	display: flex; align-items: flex-start; justify-content: space-between;
	gap: 1.5rem;
	margin-top: 1.25rem;
}

.card__title {
	font-size: clamp(1.375rem, 2.2vw, 1.875rem);
	margin-bottom: 0.4rem;
}

.card__meta {
	font-size: 0.8125rem;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	opacity: 0.6;
	margin: 0;
}

.card__arrow {
	flex: none;
	width: 2.5rem; height: 2.5rem;
	display: grid; place-items: center;
	border: 1px solid var(--rule-strong);
	border-radius: 50%;
	transition: transform 320ms var(--ease), background-color 320ms var(--ease);
}
.card:hover .card__arrow {
	transform: translate(3px, -3px);
	background: var(--ghost);
}
.card__arrow svg { width: 0.875rem; height: 0.875rem; }

/* =========================================================================
   8. INITIATIVES
   ====================================================================== */

.initiatives {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
	gap: 1px;
	background: var(--rule);
	border: 1px solid var(--rule);
	list-style: none; margin: 0; padding: 0;
}

.initiative {
	background: var(--bg);
	padding: clamp(1.75rem, 3vw, 2.5rem);
	transition: background-color 260ms var(--ease);
}
.initiative:hover { background: var(--ghost); }

.initiative__title {
	font-size: clamp(1.25rem, 1.9vw, 1.625rem);
	margin: 1.25rem 0 0.65rem;
}
.initiative p { font-size: 0.9375rem; opacity: 0.78; }

/* =========================================================================
   9. RECOMMENDATIONS
   ====================================================================== */

.quotes {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(min(21rem, 100%), 1fr));
	gap: clamp(1.5rem, 3vw, 2.5rem);
	list-style: none; margin: 0; padding: 0;
}

/* A horizontal scroller rather than a grid. Three cards visible on desktop,
   two on tablet, one on phone. Without JS it still scrolls natively — the
   arrows are an enhancement, not the only way through. */
.quotes {
	--per-view: 3;
	--quotes-gap: clamp(1.5rem, 3vw, 2.5rem);

	display: flex;
	gap: var(--quotes-gap);
	list-style: none; margin: 0; padding: 0;

	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scroll-behavior: smooth;
	/* Top-aligned, so expanding one card grows only that card instead of
	   stretching its neighbours to match. */
	align-items: flex-start;
	/* Room for focus rings, which would otherwise be clipped by overflow. */
	padding-block: 4px;

	scrollbar-width: none;
	-ms-overflow-style: none;
}
.quotes::-webkit-scrollbar { display: none; }

.quotes > li {
	flex: 0 0 calc(
		(100% - (var(--per-view) - 1) * var(--quotes-gap)) / var(--per-view)
	);
	scroll-snap-align: start;
	display: flex;
}

@media (max-width: 1024px) { .quotes { --per-view: 2; } }
@media (max-width: 700px)  { .quotes { --per-view: 1; } }

.quote {
	width: 100%;
	background: var(--surface);
	color: var(--on-surface);
	padding: clamp(1.75rem, 3vw, 2.25rem);
	border-radius: 20px;
	display: flex; flex-direction: column; gap: 1.25rem;
}

/* Body copy, so it uses the body face at the same size as the rest of the
   page. Applied to descendants too: a recommendation pasted as a WordPress
   Quote block nests its own blockquote in here, carrying italics and a serif. */
.quote__text,
.quote__text p,
.quote__text blockquote,
.quote__text span,
.quote__text em,
.quote__text cite {
	font-family: var(--font-body);
	font-style: normal;
	font-size: 1.0625rem;
	line-height: 1.6;
	letter-spacing: 0;
}
.quote__text { margin: 0; }
.quote__text p { max-width: none; margin: 0 0 0.85em; }
.quote__text p:last-child { margin-bottom: 0; }

/* Keep the Quote block's left rule, but hairline it. GeneratePress sets this
   too, so the extra .quote ancestor is there to win on specificity. */
.quote .quote__text blockquote,
.quote .quote__text .wp-block-quote {
	margin: 0;
	padding: 0 0 0 1.15rem;
	border: 0;
	border-left: 2px solid rgba(0, 0, 0, 0.05);
}
.quote__text cite { display: none; }

/* Collapsing is added by JS, so with JS off every recommendation is readable
   in full. Capping by max-height rather than line-clamp keeps multi-paragraph
   quotes working and makes the expansion animatable. */
.js-clamp .quote__text {
	transition: max-height 420ms var(--ease);
}
.js-clamp .quote__text[data-clamped="true"] {
	/* Both bounds, so every collapsed card is exactly eight lines tall — short
	   quotes pad out, long ones cut off. The floor is dropped on expand.
	   The mask eats into the last line, so eight lines reads as about seven. */
	min-height: calc(8 * 1.6em);
	max-height: calc(8 * 1.6em);
	overflow: hidden;
	-webkit-mask-image: linear-gradient(to bottom, #000 78%, transparent 100%);
	        mask-image: linear-gradient(to bottom, #000 78%, transparent 100%);
}

.quote__toggle {
	display: none;
	align-self: flex-start;
	margin-top: 0.85rem;
	padding: 0.2rem 0;
	background: none;
	border: 0;
	color: inherit;
	font-family: var(--font-body);
	font-size: 0.875rem;
	cursor: pointer;
	text-decoration: underline;
	text-underline-offset: 0.22em;
}
.quote__toggle:hover { text-decoration-thickness: 2px; }
.js-clamp .quote__toggle.is-needed { display: inline-block; }

/* Name and role.

   OPTION A (active) — Instrument Sans at 600.
   Instrument Serif ships a single weight, so it cannot go bolder. This uses
   the body face, which has a real semibold. Separation from the quote comes
   from weight and size rather than a change of family.

   OPTION B — Instrument Serif. Swap the three marked lines to go back to the
   serif name. It cannot be made bolder; get presence from size instead. */
.quote figcaption {
	margin-top: auto;
	padding-top: 0.35rem;
	line-height: 1.3;
}
.quote figcaption strong {
	display: block;
	font-family: var(--font-body);   /* OPTION B: var(--font-display) */
	font-weight: 600;                /* OPTION B: 400                */
	font-size: 1.125rem;             /* OPTION B: 1.375rem           */
	font-style: normal;
	letter-spacing: -0.005em;
	line-height: 1.25;
	margin-bottom: 0.15rem;
}
.quote figcaption span {
	display: block;
	font-size: 0.875rem;
	line-height: 1.35;
	opacity: 0.68;
}

/* Carousel arrows. The circle itself is styled with the theme toggle, up in
   the "Circular icon buttons" block — one rule for both, so they cannot
   drift apart. */
.quotes-nav {
	display: flex;
	gap: 0.75rem;
	margin-top: clamp(1.75rem, 3.5vw, 2.5rem);
}

@media (prefers-reduced-motion: reduce) {
	.js-clamp .quote__text { transition: none; }
	.quotes { scroll-behavior: auto; }
}

/* =========================================================================
   10. ABOUT
   ====================================================================== */

.about {
	display: grid;
	grid-template-columns: minmax(0, 1fr);
	gap: clamp(2rem, 5vw, 4.5rem);
	align-items: start;
}
@media (min-width: 900px) {
	.about { grid-template-columns: 22rem minmax(0, 1fr); }
}

.about__portrait {
	border-radius: 3px;
	background: var(--surface);
	aspect-ratio: 4 / 5;
	object-fit: cover;
	width: 100%;
}

.about__body p { font-size: clamp(1.0625rem, 1.5vw, 1.1875rem); }

/* =========================================================================
   11. CONTACT + FOOTER
   ====================================================================== */

.contact__lead {
	font-family: var(--font-display);
	font-size: clamp(2rem, 5.5vw, 4.5rem);
	line-height: 1.05;
	max-width: 18ch;
	margin: 0 0 clamp(2rem, 4vw, 3rem);
}

.contact__links {
	display: flex; flex-wrap: wrap; gap: 1rem 2.5rem;
	font-size: 1.0625rem;
	list-style: none; margin: 0; padding: 0;
}

.site-footer {
	border-top: 1px solid var(--rule);
	padding-block: 2.5rem;
	font-size: 0.875rem;
}
.site-footer__inner {
	display: flex; flex-wrap: wrap; gap: 0.75rem 2rem;
	justify-content: space-between;
	opacity: 0.7;
}

/* =========================================================================
   12. CASE STUDY TEMPLATE
   ====================================================================== */

.cs-hero { padding-block: clamp(4rem, 10vh, 7rem) clamp(2.5rem, 5vw, 4rem); }

.cs-hero__title {
	font-size: clamp(2.5rem, 6.4vw, 5.5rem);
	max-width: 16ch;
	margin: 1.5rem 0 0;
}

.cs-facts {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
	gap: 1.5rem 2.5rem;
	margin-top: clamp(2.5rem, 5vw, 4rem);
	padding-top: 1.5rem;
	border-top: 1px solid var(--rule);
	list-style: none;
	padding-inline: 0;
}
.cs-facts dt {
	font-size: 0.75rem; letter-spacing: 0.12em; text-transform: uppercase;
	opacity: 0.55; margin-bottom: 0.35rem;
}
.cs-facts dd { margin: 0; font-size: 0.9375rem; }

.cs-cover { margin-block: clamp(2rem, 5vw, 4rem); }
.cs-cover img { width: 100%; border-radius: 3px; }

/* The article body: a single readable column, images allowed to break out. */
.cs-body { padding-bottom: var(--section-y); }
.cs-body > * {
	max-width: var(--measure);
	margin-inline: auto;
}
.cs-body h2 {
	font-size: clamp(1.75rem, 3.4vw, 2.75rem);
	margin: clamp(3rem, 6vw, 4.5rem) 0 1rem;
}
.cs-body h3 {
	font-size: clamp(1.3125rem, 2.2vw, 1.75rem);
	margin: clamp(2rem, 4vw, 3rem) 0 0.75rem;
}
.cs-body figure,
.cs-body .alignwide,
.cs-body .wp-block-image {
	max-width: min(100%, 1100px);
	margin-block: clamp(2rem, 5vw, 3.5rem);
}
.cs-body figcaption {
	font-size: 0.8125rem;
	opacity: 0.65;
	margin-top: 0.75rem;
	text-align: left;
}
.cs-body blockquote {
	border-left: 2px solid var(--rule-strong);
	padding-left: 1.5rem;
	margin-inline: auto;
	font-family: var(--font-display);
	font-size: clamp(1.25rem, 2vw, 1.625rem);
	line-height: 1.35;
}

.cs-next {
	border-top: 1px solid var(--rule);
	padding-block: clamp(3rem, 6vw, 5rem);
}
.cs-next__title { font-size: clamp(1.75rem, 3.6vw, 3rem); margin-top: 0.5rem; }

/* =========================================================================
   13. SCROLL REVEAL
   Opt-in: elements start hidden ONLY when JS has confirmed it will reveal
   them. Without this guard, a JS failure leaves the page blank.
   ====================================================================== */

.js-reveal [data-reveal] {
	opacity: 0;
	transform: translateY(18px);
	transition: opacity 700ms var(--ease), transform 700ms var(--ease);
}
.js-reveal [data-reveal].is-visible {
	opacity: 1;
	transform: none;
}

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*,
	*::before,
	*::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
	.js-reveal [data-reveal] { opacity: 1; transform: none; }
}

/* =========================================================================
   14. PRINT — someone will print your portfolio before an interview
   ====================================================================== */

@media print {
	.site-header, .theme-toggle, .cs-next { display: none; }
	body { background: #fff; color: #000; }
	.section { padding-block: 1.5rem; }
}
