22< html lang ="en ">
33< head >
44 < meta charset ="UTF-8 " />
5- < meta name ="viewport " content ="width=device-width,initial-scale=1 " />
65 < title > Get Started: Logging In</ title >
7-
8- <!-- Keep your global layout (header/sidebar) -->
9- < link rel ="stylesheet " href ="./style.css " />
10- < link rel ="icon " href ="data:, ">
11-
126 < style >
13- /* ===== page-scoped overrides so the hero fills the content pane ===== */
14- : root {
15- --header-h : 56px ; /* adjust if your sticky header differs */
16- /* screenshot colors */
17- --bg1 : # 3657f0 ; /* left gradient */
18- --bg2 : # e36ccf ; /* right gradient */
19- --copy : # ffffff ;
7+ : root {
8+ --bg1 : # 3657f0 ;
9+ --bg2 : # e36ccf ;
2010 --card-border : # ffffff ;
21- --author : # EBAAF2 ; /* lilac */
22- --instructor : # 99cdb5 ; /* mint */
23- --student : # 0a4cc5 ; /* deep blue */
24- }
25-
26- body .page-login .content {
27- padding : 0 !important ; /* remove 24px gutters on this page */
28- position : relative !important ; /* anchor absolute hero */
29- }
30- /* neutralize common width-limiting wrappers from templates */
31- body .page-login .video-container ,
32- body .page-login .title-bar ,
33- body .page-login .page-content {
34- max-width : none !important ;
35- margin : 0 !important ;
36- padding : 0 !important ;
37- border : 0 !important ;
38- box-shadow : none !important ;
11+ --author : # EBAAF2 ;
12+ --instructor : # 99cdb5 ;
13+ --student : # 0a4cc5 ;
14+ }
15+
16+ /* === The full content pane background === */
17+ # login-hero {
18+ position : absolute;
19+ inset : 0 ; /* fill the entire .content area */
20+ width : 100% ;
21+ height : 100% ;
22+ background : linear-gradient (135deg , var (--bg1 ), var (--bg2 ));
23+ display : flex;
24+ justify-content : center;
25+ align-items : center;
26+ overflow : hidden; /* never scroll */
3927 }
4028
41- /* ===== the hero fills the entire content pane (right of sidebar) ===== */
42- # login-hero {
43- position : absolute; inset : 0 ; /* edge-to-edge in .content */
29+ /* === Fixed canvas (1440x900) === */
30+ # login-hero .inner {
31+ width : 1440px ;
32+ height : 900px ;
4433 display : grid;
45- align-content : start; /* start like the screenshot */
46- gap : clamp (20px , 3vw , 32px );
47- padding : clamp (24px , 5vw , 60px );
48- color : var (--copy );
49- background : linear-gradient (135deg , var (--bg1 ), var (--bg2 ));
50- border-radius : 0 ; /* true bleed */
51- min-height : calc (100vh - var (--header-h )); /* fallback */
34+ grid-template-rows : auto 1fr auto;
35+ justify-items : center;
36+ align-items : center;
37+ padding : 40px ;
38+ box-sizing : border-box;
39+ color : # fff ;
5240 }
5341
54- /* headline block */
55- # login-hero h1 {
56- margin : 0 0 10 px 0 ;
42+ # login-hero h1 {
43+ margin : 0 ;
44+ font-size : 64 px ;
5745 font-weight : 800 ;
58- font-size : clamp (42px , 7vw , 84px ); /* big like screenshot */
59- line-height : 1.1 ;
60- letter-spacing : .2px ;
61- position : relative;
62- }
63- # login-hero h1 ::after { /* subtle underline bar */
64- content : "" ;
65- position : absolute; left : 0 ; bottom : -10px ;
66- width : clamp (180px , 30vw , 420px ); height : 6px ;
67- border-radius : 999px ;
68- background : linear-gradient (90deg , # 7ad7ff, # b0f, # 7ad7ff );
69- opacity : .9 ;
70- }
71-
72- /* explanatory copy */
73- # login-hero .lede {
74- margin : 18px 0 0 0 ;
75- font-size : clamp (16px , 1.4vw , 20px );
76- line-height : 1.7 ;
77- }
78-
79-
80- /* 1) Grid: enforce big gaps + wrapping, center items in each column */
81- # login-hero .grid {
82- display : grid;
83- grid-template-columns : repeat (3 , minmax (0 , 1fr )); /* stable 3 cols */
84- column-gap : clamp (24px , 4vw , 48px ); /* bigger horizontal gap */
85- row-gap : clamp (28px , 5vw , 56px ); /* bigger vertical gap */
86- justify-items : center; /* center the card in each track */
87- align-items : start;
46+ text-align : center;
8847 }
8948
90- /* 2) Cards: let the grid decide width, just cap it so they’re “thinner” */
91- .role-card {
92- width : 100% ; /* fill its grid track (so no overflow) */
93- max-width : 300px ; /* ← thinner cap (tune 280–320px to taste) */
94- /* keep your min-height from earlier (tall look) */
95- /* e.g.: min-height: clamp(260px, 28vh, 360px); */
49+ # login-hero .lede {
50+ font-size : 20px ;
51+ max-width : 800px ;
52+ text-align : center;
53+ margin : 20px 0 ;
9654 }
9755
98- /* 3) Breakpoints still 3 → 2 → 1 (no horizontal crowding) */
99- @media (max-width : 1100px ){
100- # login-hero .grid { grid-template-columns : repeat (2 , minmax (0 , 1fr )); }
101- }
102- @media (max-width : 720px ){
103- # login-hero .grid { grid-template-columns : 1fr ; }
104- .role-card { max-width : 420px ; } /* give mobile a bit more width */
56+ # login-hero .grid {
57+ display : grid;
58+ grid-template-columns : repeat (3 , 1fr );
59+ gap : 40px ;
60+ margin : 40px 0 ;
10561 }
10662
107-
108- /* cards exactly like screenshot: thick white border + rounded + shadow */
109- .role-card {
110- text-align : initial;
111- gap : 12px ;
112- align-items : center;
113- display : flex; flex-direction : column; justify-content : center;
114- min-height : clamp (400px , 28vh , 360px ); /* was 220px */
115- padding : clamp (18px , 2.8vw , 32px );
63+ .role-card {
64+ width : 280px ;
65+ height : 280px ;
11666 border-radius : 20px ;
117- border : 5px solid var (--card-border );
118- color : # fff ;
119- text-align : left;
120- box-shadow : 0 8px 28px rgba (0 , 0 , 0 , .18 );
121- cursor : grab; user-select : none; outline : none;
122- transition : transform .12s ease, box-shadow .12s ease, background .12s ease;
123- }
124- .role-card : active { cursor : grabbing; }
125- .role-card : hover ,
126- .role-card : focus-visible {
127- transform : translateY (-2px );
128- box-shadow : 0 12px 32px rgba (0 , 0 , 0 , .22 );
67+ border : 4px solid var (--card-border );
68+ display : flex;
69+ flex-direction : column;
70+ justify-content : center;
71+ align-items : center;
72+ box-shadow : 0 8px 24px rgba (0 , 0 , 0 , .2 );
73+ text-align : center;
74+ cursor : pointer;
75+ font-size : 18px ;
76+ padding : 20px ;
12977 }
13078
131- .role-card h2 {
132- text-align : center;
133- text-wrap : balance; /* modern browsers balance multi-line headings */
134- margin : 0 0 6px ;
135- }
136- .role-card p {
137- max-width : 28ch ; /* ~28 characters per line reads well in narrow cards */
138- text-align : left;
139- margin : 0 auto; /* center the paragraph block inside the card */
140- line-height : 1.55 ;
141- font-size : clamp (15px , 1.1vw , 18px );
142- text-wrap : pretty; /* nicer breaks when supported */
143- hyphens : auto; /* helps avoid ugly gaps; ensure <html lang="en"> */
144- }
145-
79+ .role-card h2 {
80+ margin : 0 0 10px ;
81+ font-size : 24px ;
82+ }
14683
14784 .role-card .author { background : var (--author ); }
14885 .role-card .instructor { background : var (--instructor ); }
14986 .role-card .student { background : var (--student ); }
15087
151- .role-card : hover ,
152- .role-card : focus-visible {
153- filter : brightness (1.06 ) saturate (1.02 ); /* subtle lift */
154- box-shadow : 0 12px 32px rgba (0 , 0 , 0 , .22 ); /* a bit deeper shadow */
155- border-color : rgba (255 , 255 , 255 , .95 ); /* slightly brighter border */
156- transform : translateY (-2px );
157- }
158-
159- /* optional soft sheen overlay (keeps bg intact) */
160- .role-card ::after {
161- content : "" ;
162- position : absolute; inset : 0 ; border-radius : inherit;
163- background : linear-gradient (180deg , rgba (255 , 255 , 255 , .08 ), rgba (255 , 255 , 255 , 0 ));
164- opacity : 0 ; pointer-events : none;
165- transition : opacity .14s ease;
88+ # login-hero .note {
89+ font-size : 16px ;
90+ font-weight : bold;
91+ text-align : center;
16692 }
167- .role-card : hover ::after ,
168- .role-card : focus-visible ::after {
169- opacity : 1 ;
170- }
171-
172-
173- /* footer note */
174- # login-hero .note {
175- margin-top : clamp (18px , 3vw , 28px );
176- font-weight : 800 ;
177- text-decoration : underline;
178- text-underline-offset : 4px ;
179- text-decoration-thickness : 2px ;
180- font-size : clamp (15px , 1.1vw , 20px );
181- }
182-
183- /* drag ghost (layout stays fixed) */
184- .drag-ghost {
185- position : fixed;
186- z-index : 9999 ;
187- pointer-events : none;
188- box-shadow : 0 12px 32px rgba (0 , 0 , 0 , .28 );
189- transform : scale (1.02 );
190- border-radius : 20px ;
191- will-change : transform, left, top;
192- }
193- .drag-origin--dim { opacity : .65 ; }
19493 </ style >
19594</ head >
19695
19796< body class ="page-login ">
198- <!-- Rendered inside your app’s .content pane (right of sidebar). -->
199- < main >
200- < section id ="login-hero " aria-labelledby ="title ">
97+ < section id ="login-hero " aria-labelledby ="title ">
98+ < div class ="inner ">
20199 < h1 id ="title "> Get Started: < em > Logging In</ em > </ h1 >
202100
203101 < p class ="lede ">
204102 Torus incorporates features and a specialized interface for course authors, instructors, and students. Select your primary role below to start a customized tutorial tailored to your needs!
205103 </ p >
206104
207105 < section class ="grid " aria-label ="Choose your role ">
208- <!-- Update data-target values to your exact sidebar/page titles -->
209106 < button class ="role-card author " data-target ="Create a New Project " aria-label ="Author ">
210107 < h2 > Author</ h2 >
211108 < p > I am designing, developing, or editing course content.</ p >
@@ -225,90 +122,19 @@ <h2>Student</h2>
225122 < p class ="note ">
226123 You can return to this home page any time to start a tutorial for a different role.
227124 </ p >
228- </ section >
229- </ main >
125+ </ div >
126+ </ section >
230127
231128 < script >
232- /* click → navigate (same custom event your search overlay handles) */
129+ // Card click → trigger tutorial navigation
233130 document . querySelectorAll ( '#login-hero .role-card' ) . forEach ( card => {
234131 card . addEventListener ( 'click' , ( ) => {
235132 const title = card . dataset . target ;
236133 if ( title ) {
237134 window . dispatchEvent ( new CustomEvent ( 'search:openTutorial' , { detail : { title } } ) ) ;
238- window . scrollTo ( { top : 0 , behavior : 'smooth' } ) ;
239135 }
240136 } ) ;
241-
242- /* drag ghost: original card stays put; layout never reflows */
243- card . setAttribute ( 'draggable' , 'false' ) ;
244- card . style . touchAction = 'none' ;
245- card . addEventListener ( 'pointerdown' , onDown ) ;
246137 } ) ;
247-
248- let ghost = null , origin = null , dx = 0 , dy = 0 ;
249-
250- function onDown ( e ) {
251- if ( e . button !== 0 ) return ;
252- origin = e . currentTarget ;
253- const r = origin . getBoundingClientRect ( ) ;
254- dx = e . clientX - r . left ; dy = e . clientY - r . top ;
255-
256- ghost = origin . cloneNode ( true ) ;
257- ghost . classList . add ( 'drag-ghost' ) ;
258- Object . assign ( ghost . style , {
259- width : r . width + 'px' ,
260- height : r . height + 'px' ,
261- left : ( e . clientX - dx ) + 'px' ,
262- top : ( e . clientY - dy ) + 'px'
263- } ) ;
264- document . body . appendChild ( ghost ) ;
265-
266- origin . classList . add ( 'drag-origin--dim' ) ;
267- origin . setPointerCapture ( e . pointerId ) ;
268- window . addEventListener ( 'pointermove' , onMove ) ;
269- window . addEventListener ( 'pointerup' , onUp , { once : true } ) ;
270- }
271-
272- function onMove ( e ) {
273- if ( ! ghost ) return ;
274- ghost . style . left = ( e . clientX - dx ) + 'px' ;
275- ghost . style . top = ( e . clientY - dy ) + 'px' ;
276- }
277-
278- function onUp ( ) {
279- window . removeEventListener ( 'pointermove' , onMove ) ;
280- if ( ! ghost || ! origin ) return ;
281-
282- const r = origin . getBoundingClientRect ( ) ;
283- const gx = parseFloat ( ghost . style . left ) || 0 ;
284- const gy = parseFloat ( ghost . style . top ) || 0 ;
285- const tx = r . left - gx ;
286- const ty = r . top - gy ;
287-
288- ghost . style . transition = 'transform 160ms ease, opacity 160ms ease' ;
289- ghost . style . transform = `translate(${ tx } px, ${ ty } px)` ;
290- ghost . style . opacity = '0.6' ;
291-
292- setTimeout ( ( ) => {
293- ghost . remove ( ) ;
294- ghost = null ;
295- origin . classList . remove ( 'drag-origin--dim' ) ;
296- origin = null ;
297- } , 170 ) ;
298- }
299-
300- /* If opened standalone (without .content), still fill viewport */
301- ( function ensureMinHeight ( ) {
302- const hero = document . getElementById ( 'login-hero' ) ;
303- if ( ! hero ) return ;
304- function fit ( ) {
305- if ( ! document . querySelector ( '.content' ) ) {
306- hero . style . minHeight = `calc(100vh - var(--header-h))` ;
307- }
308- }
309- window . addEventListener ( 'load' , fit , { once :true } ) ;
310- window . addEventListener ( 'resize' , fit ) ;
311- } ) ( ) ;
312138 </ script >
313139</ body >
314140</ html >
0 commit comments