/* ========================================================================== Font Definitions ========================================================================== */ @font-face { font-family: "Outline"; src: url("../fonts/Outline-Regular.woff2") format("woff2"), url("../fonts/Outline-Regular.woff") format("woff"); font-weight: 400; font-style: normal; font-display: swap; } @font-face { font-family: "Outline"; src: url("../fonts/Outline-Light.woff2") format("woff2"), url("../fonts/Outline-Light.woff") format("woff"); font-weight: 300; font-style: normal; font-display: swap; } /* ========================================================================== CSS Reset & Normalize (Modern Best Practices) Based on normalize.css v8.0.1 + modern resets ========================================================================== */ /* Box sizing rules */ *, *::before, *::after { box-sizing: border-box; } /* Prevent font size inflation */ html { -moz-text-size-adjust: none; -webkit-text-size-adjust: none; text-size-adjust: none; } /* Remove default margin and padding */ * { margin: 0; padding: 0; } /* Set core root defaults */ html { font-size: 16px; line-height: 1.5; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } /* Set core body defaults */ body { min-height: 100vh; font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; line-height: 1.5; text-rendering: optimizeSpeed; } /* Remove list styles on ul, ol elements */ ul, ol { list-style: none; } /* Anchor elements that don't have a class get default styles */ a:not([class]) { text-decoration-skip-ink: auto; } /* Make images easier to work with */ img, picture, video, canvas, svg { display: block; max-width: 100%; height: auto; } /* Inherit fonts for inputs and buttons */ input, button, textarea, select { font: inherit; color: inherit; } /* Remove default button styles */ button { background: none; border: none; cursor: pointer; } /* Make sure textareas without a rows attribute are not tiny */ textarea:not([rows]) { min-height: 10em; } /* Anything that has been anchored to should have extra scroll margin */ :target { scroll-margin-block: 5ex; } /* Remove all animations, transitions and smooth scroll for people that prefer not to see them */ @media (prefers-reduced-motion: reduce) { html:focus-within { scroll-behavior: auto; } *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; } } /* Remove the inner border and padding in Firefox */ ::-moz-focus-inner { border-style: none; padding: 0; } /* Restore the focus styles unset by the previous rule */ :-moz-focusring { outline: 1px dotted ButtonText; } /* Remove the additional ':invalid' styles in Firefox */ :-moz-ui-invalid { box-shadow: none; } /* Correct the cursor style of increment and decrement buttons in Safari */ ::-webkit-inner-spin-button, ::-webkit-outer-spin-button { height: auto; } /* Correct the outline style in Safari */ [type="search"] { outline-offset: -2px; } /* Remove the inner padding in Chrome and Safari on macOS */ ::-webkit-search-decoration { -webkit-appearance: none; } /* Correct the inability to style clickable types in iOS and Safari */ ::-webkit-file-upload-button { -webkit-appearance: button; font: inherit; } /* Interactive elements */ summary { display: list-item; } /* Table */ table { border-collapse: collapse; border-spacing: 0; } /* ========================================================================== CSS Custom Properties (Design Tokens) ========================================================================== */ :root { /* Colors */ --color-primary: #2563eb; --color-primary-dark: #1d4ed8; --color-secondary: #64748b; --color-accent: #f59e0b; --color-text: #1e293b; --color-text-light: #64748b; --color-text-inverse: #ffffff; --color-background: #ffffff; --color-background-secondary: #f8fafc; --color-background-tertiary: #f1f5f9; --color-border: #e2e8f0; --color-border-light: #f1f5f9; --color-push-box-bg: #EBEEF4; --color-success: #22c55e; --color-error: #ef4444; --color-warning: #f59e0b; /* Typography */ --font-family-base: "Outline", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; --font-family-heading: var(--font-family-base); --font-family-outfit: "Outfit", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; --font-size-xs: 0.75rem; /* 12px */ --font-size-sm: 0.875rem; /* 14px */ --font-size-base: 1rem; /* 16px */ --font-size-lg: 1.125rem; /* 18px */ --font-size-xl: 1.25rem; /* 20px */ --font-size-2xl: 1.5rem; /* 24px */ --font-size-3xl: 1.875rem; /* 30px */ --font-weight-light: 300; --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-semibold: 600; --font-weight-bold: 700; --line-height-tight: 1.25; --line-height-normal: 1.5; /* 24px at 16px base */ --line-height-relaxed: 1.75; --line-height-24: 24px; /* Spacing */ --spacing-xs: 0.25rem; /* 4px */ --spacing-sm: 0.5rem; /* 8px */ --spacing-md: 1rem; /* 16px */ --spacing-lg: 1.5rem; /* 24px */ --spacing-xl: 2rem; /* 32px */ --spacing-2xl: 3rem; /* 48px */ /* Border Radius */ --radius-sm: 0.25rem; /* 4px */ --radius-md: 0.5rem; /* 8px */ --radius-lg: 0.75rem; /* 12px */ --radius-xl: 1rem; /* 16px */ --radius-full: 9999px; /* Shadows */ --shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); --shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); --shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1); /* Transitions */ --transition-fast: 150ms ease; --transition-normal: 250ms ease; --transition-slow: 350ms ease; /* Layout */ --mobile-max-width: 430px; --header-height: auto; --footer-height: auto; } /* ========================================================================== Base Styles ========================================================================== */ body { font-family: var(--font-family-base); font-size: var(--font-size-base); color: var(--color-text); background-color: var(--color-background-secondary); } /* ========================================================================== Top Bar Slotted Content Styles ========================================================================== */ top-bar .icon-button { display: flex; align-items: center; justify-content: center; width: 32px; height: 32px; background: transparent; border: none; cursor: pointer; padding: 0; } top-bar .icon-button svg { width: 32px; height: 32px; } top-bar .logo { font-family: var(--font-family-base); font-size: var(--font-size-xl); font-weight: var(--font-weight-bold); color: #ffffff; text-decoration: none; } top-bar .actions { display: flex; align-items: center; gap: var(--spacing-md); } /* ========================================================================== Mobile Container (for desktop viewing) Centers content in a phone-sized container on larger screens ========================================================================== */ .mobile-container { width: 100%; min-height: 100vh; margin: 0 auto; background-color: var(--color-background); position: relative; } @media (min-width: 431px) { body { display: flex; justify-content: center; align-items: flex-start; padding: var(--spacing-lg) 0; } .mobile-container { max-width: var(--mobile-max-width); min-height: calc(100vh - var(--spacing-lg) * 2); border-radius: var(--radius-xl); box-shadow: var(--shadow-lg); overflow: hidden; } } /* ========================================================================== Utility Classes ========================================================================== */ .visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } .truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .truncate-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; } /* ========================================================================== Page Components ========================================================================== */ /* Section */ .section { margin-bottom: var(--spacing-xl); } .section-title { font-size: var(--font-size-lg); font-weight: var(--font-weight-semibold); color: var(--color-text); margin-bottom: var(--spacing-md); } .section-heading { font-size: var(--font-size-base); font-weight: var(--font-weight-semibold); color: var(--color-text); margin-bottom: var(--spacing-md); } /* Book Grid */ .book-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--spacing-md); } /* ========================================================================== Book Detail Page ========================================================================== */ .book-detail { display: flex; flex-direction: column; gap: var(--spacing-lg); } /* Back Link */ .back-link { display: inline-flex; align-items: center; gap: var(--spacing-xs); font-size: var(--font-size-sm); color: var(--color-text-light); text-decoration: none; transition: color var(--transition-fast); } .back-link:hover { color: var(--color-primary); } /* Book Cover */ .book-cover { display: flex; justify-content: center; } .book-cover-placeholder { width: 180px; height: 270px; background-color: var(--color-background-tertiary); border-radius: var(--radius-lg); display: flex; align-items: center; justify-content: center; color: var(--color-text-light); box-shadow: var(--shadow-md); } .book-cover-placeholder svg { width: 64px; height: 64px; opacity: 0.5; } .book-cover img { width: 180px; height: auto; border-radius: var(--radius-lg); box-shadow: var(--shadow-md); } /* Book Info */ .book-info { text-align: center; } .book-title { font-size: var(--font-size-2xl); font-weight: var(--font-weight-bold); color: var(--color-text); margin-bottom: var(--spacing-xs); line-height: var(--line-height-tight); } .book-author { font-size: var(--font-size-base); color: var(--color-text-light); margin-bottom: var(--spacing-md); } .book-rating { display: flex; align-items: center; justify-content: center; gap: var(--spacing-sm); margin-bottom: var(--spacing-md); } .book-rating .stars { display: flex; gap: 2px; } .book-rating .stars svg { width: 18px; height: 18px; color: var(--color-accent); } .rating-text { font-size: var(--font-size-sm); color: var(--color-text-light); } .book-meta { display: flex; justify-content: center; gap: var(--spacing-lg); padding: var(--spacing-md); background-color: var(--color-background-tertiary); border-radius: var(--radius-lg); } .meta-item { display: flex; flex-direction: column; align-items: center; gap: var(--spacing-xs); } .meta-label { font-size: var(--font-size-xs); color: var(--color-text-light); text-transform: uppercase; letter-spacing: 0.05em; } .meta-value { font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); color: var(--color-text); } /* Purchase Section */ .purchase-section { padding: var(--spacing-md); background-color: var(--color-background-secondary); border-radius: var(--radius-lg); } .price-container { display: flex; align-items: center; gap: var(--spacing-sm); margin-bottom: var(--spacing-md); } .current-price { font-size: var(--font-size-2xl); font-weight: var(--font-weight-bold); color: var(--color-text); } .original-price { font-size: var(--font-size-base); color: var(--color-text-light); text-decoration: line-through; } .discount-badge { padding: var(--spacing-xs) var(--spacing-sm); font-size: var(--font-size-xs); font-weight: var(--font-weight-semibold); color: var(--color-text-inverse); background-color: var(--color-success); border-radius: var(--radius-sm); } .purchase-actions { display: flex; gap: var(--spacing-sm); } /* Buttons */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--spacing-sm); padding: var(--spacing-sm) var(--spacing-md); font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); border-radius: var(--radius-lg); border: none; cursor: pointer; transition: all var(--transition-fast); } .btn-primary { flex: 1; color: var(--color-text-inverse); background-color: var(--color-primary); } .btn-primary:hover { background-color: var(--color-primary-dark); } .btn-secondary { padding: var(--spacing-sm); color: var(--color-text); background-color: var(--color-background); border: 1px solid var(--color-border); } .btn-secondary:hover { background-color: var(--color-background-tertiary); } .btn-outline { color: var(--color-primary); background-color: transparent; border: 1px solid var(--color-primary); } .btn-outline:hover { background-color: var(--color-primary); color: var(--color-text-inverse); } .btn-large { padding: var(--spacing-md) var(--spacing-lg); font-size: var(--font-size-base); } .btn-full { width: 100%; } /* Book Description */ .book-description p { font-size: var(--font-size-sm); color: var(--color-text); line-height: var(--line-height-relaxed); margin-bottom: var(--spacing-md); } .book-description p:last-child { margin-bottom: 0; } /* Reviews Section */ .reviews-section { display: flex; flex-direction: column; gap: var(--spacing-md); } .review-card { padding: var(--spacing-md); background-color: var(--color-background-secondary); border-radius: var(--radius-lg); } .review-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: var(--spacing-sm); } .reviewer-info { display: flex; flex-direction: column; } .reviewer-name { font-size: var(--font-size-sm); font-weight: var(--font-weight-semibold); color: var(--color-text); } .review-date { font-size: var(--font-size-xs); color: var(--color-text-light); } .review-stars { display: flex; gap: 2px; } .review-stars svg { width: 14px; height: 14px; color: var(--color-accent); } .review-text { font-size: var(--font-size-sm); color: var(--color-text); line-height: var(--line-height-normal); }