Repository: ParabolInc/parabol
Pull request #10931: fix: line height, padding for editor instances
Author: login: ackernaut
Labels: name: size/m
Created: 2025-02-26T22:04:17Z | Merged: 2025-03-05T17:52:06Z

- Moves inner style concerns from `<TipTapEditor />` component to specific components using the editor
- Fixes #10775  line-height to match designs
- Fixes #10776  thread comment indention
- Removes truncation from reflection cards in Discuss phase. Users can see all the text without scrolling
- Bumps truncated retro card height from ~5 lines to 7 lines of text without returns

Linked issue #10775: Fixed line height for editable content
Before migrating to Tiptap we had 14/20 on cards and comments. Now it’s 14/16. It seems we could fix this in one place?

Filing it as a styling issue bug.

Also see #10683 as it has the 16px line height, too.

### Acceptance criteria
- Editable text is 14/20 anywhere we’re editing surface:
  - Stand-up card prompt editor
  - Thread comment input
  - Thread comment
  - Retro card input
  - Retro card
  - Poker item, Parabol task in Scope phase
  - Poker item, Parabol task in Estimate phase
  - Task card
  - Notifications (Discussions, Replies, Task Involves)
  - Page beta

### Estimated effort
- 4 hours

Diff:
diff --git a/packages/client/components/DiscussionThreadInput.tsx b/packages/client/components/DiscussionThreadInput.tsx
index 095fdf3ed21..4038e949238 100644
--- a/packages/client/components/DiscussionThreadInput.tsx
+++ b/packages/client/components/DiscussionThreadInput.tsx
@@ -214,10 +214,7 @@ const DiscussionThreadInput = (props: Props) => {
     >
       <div className='flex items-center justify-center p-1'>
         <Avatar picture={avatar} onClick={toggleAnonymous} className='m-2 h-8 w-8 transition-all' />
-        <TipTapEditor
-          className='flex max-h-80 min-h-0 grow overflow-auto px-0 leading-4'
-          editor={editor}
-        />
+        <TipTapEditor className='flex max-h-80 grow overflow-auto leading-4' editor={editor} />
         <SendCommentButton commentSubmitState={commentSubmitState} onSubmit={onSubmit} />
       </div>
       {isActionsContainerVisible && (
diff --git a/packages/client/components/EditableText.tsx b/packages/client/components/EditableText.tsx
index 8436ad1246d..178a4f58e97 100644
--- a/packages/client/components/EditableText.tsx
+++ b/packages/client/components/EditableText.tsx
@@ -70,8 +70,14 @@ const TextArea = styled(TextAreaAutoSize)({
 })
 
 const Form = styled('form')({
+  border: 0,
   display: 'flex',
-  flexDirection: 'column'
+  flexDirection: 'column',
+  fontSize: 'inherit',
+  fontWeight: 'inherit',
+  lineHeight: 'inherit',
+  margin: 0,
+  padding: 0
 })
 
 interface Props {
diff --git a/packages/client/components/EditingStatus/EditingStatus.tsx b/packages/client/components/EditingStatus/EditingStatus.tsx
index e30e81e34fb..9ed7b257aec 100644
--- a/packages/client/components/EditingStatus/EditingStatus.tsx
+++ b/packages/client/components/EditingStatus/EditingStatus.tsx
@@ -22,7 +22,7 @@ const StatusHeader = styled('div')({
   justifyContent: 'space-between',
   lineHeight: '20px',
   minHeight: Card.BUTTON_HEIGHT,
-  padding: `0 ${Card.PADDING} 8px`,
+  padding: `0 ${Card.PADDING} 4px`,
   textAlign: 'left'
 })
 
diff --git a/packages/client/components/ParabolScopingSearchResultItem.tsx b/packages/client/components/ParabolScopingSearchResultItem.tsx
index 00150584c27..feb687fb689 100644
--- a/packages/client/components/ParabolScopingSearchResultItem.tsx
+++ b/packages/client/components/ParabolScopingSearchResultItem.tsx
@@ -140,7 +140,11 @@ const ParabolScopingSearchResultItem = (props: Props) => {
           addTaskChild('root')
         }}
       >
-        <TipTapEditor editor={editor} useLinkEditor={() => useTaskChild('editor-link-changer')} />
+        <TipTapEditor
+          className='px-4'
+          editor={editor}
+          useLinkEditor={() => useTaskChild('editor-link-changer')}
+        />
       </Task>
     </Item>
   )
diff --git a/packages/client/components/ReflectionCard/ReflectionCard.tsx b/packages/client/components/ReflectionCard/ReflectionCard.tsx
index 183cb5c9c3d..d65b6fee419 100644
--- a/packages/client/components/ReflectionCard/ReflectionCard.tsx
+++ b/packages/client/components/ReflectionCard/ReflectionCard.tsx
@@ -36,7 +36,7 @@ import ReflectionCardDeleteButton from './ReflectionCardDeleteButton'
 import ReflectionCardRoot from './ReflectionCardRoot'
 
 const StyledReacjis = styled(ReactjiSection)({
-  padding: '0 14px 12px'
+  padding: '4px 16px 0'
 })
 
 const SpotlightIcon = styled(IconLabel)({
@@ -317,18 +317,18 @@ const ReflectionCard = (props: Props) => {
       onMouseLeave={() => setIsHovering(false)}
       showDragHintAnimation={showDragHintAnimation}
       ref={reflectionDivRef}
-      className='py-2'
+      className='py-3'
     >
       <ColorBadge phaseType={phaseType as NewMeetingPhaseTypeEnum} reflection={reflection} />
 
       <div
         ref={scrollRef}
-        className={cn('relative w-full overflow-auto text-sm leading-4 text-slate-700')}
+        className={cn('relative w-full overflow-auto text-sm leading-5 text-slate-700')}
       >
         <TipTapEditor
           className={cn(
-            'flex min-h-4 w-full px-4',
-            isClipped ? 'max-h-8' : 'max-h-28',
+            'flex min-h-6 w-full px-4',
+            phaseType === 'discuss' ? undefined : isClipped ? 'max-h-6' : 'max-h-41',
             readOnly ? (phaseType === 'discuss' ? 'select-text' : 'select-none') : undefined
           )}
           editor={editor}
diff --git a/packages/client/components/ReflectionCard/ReflectionCardAuthor.tsx b/packages/client/components/ReflectionCard/ReflectionCardAuthor.tsx
index 408b1a5926a..d37989f0b4a 100644
--- a/packages/client/components/ReflectionCard/ReflectionCardAuthor.tsx
+++ b/packages/client/components/ReflectionCard/ReflectionCardAuthor.tsx
@@ -4,8 +4,9 @@ import {PALETTE} from '../../styles/paletteV3'
 const Author = styled('div')({
   padding: '2px 16px',
   color: PALETTE.SLATE_600,
-  fontSize: 14,
-  fontWeight: 700,
+  fontSize: 13,
+  fontWeight: 600,
+  lineHeight: '20px',
   whiteSpace: 'nowrap',
   textOverflow: 'ellipsis',
   overflow: 'hidden'
diff --git a/packages/client/components/ReflectionGroup/RemoteReflection.tsx b/packages/client/components/ReflectionGroup/RemoteReflection.tsx
index a6280119db9..127f3501ed6 100644
--- a/packages/client/components/ReflectionGroup/RemoteReflection.tsx
+++ b/packages/client/components/ReflectionGroup/RemoteReflection.tsx
@@ -284,9 +284,13 @@ const RemoteReflection = (props: Props) => {
       >
         <ReflectionCardRoot>
           {!headerTransform && <UserDraggingHeader userId={dragUserId} name={dragUserName} />}
-          <HTMLReflection html={html} disableAnonymity={disableAnonymity} />
+          <div className='py-[2px]'>
+            <HTMLReflection html={html} disableAnonymity={disableAnonymity} />
+          </div>
           {disableAnonymity && (
-            <ReflectionCardAuthor>{creator?.preferredName}</ReflectionCardAuthor>
+            <div className='pb-3'>
+              <ReflectionCardAuthor>{creator?.preferredName}</ReflectionCardAuthor>
+            </div>
           )}
         </ReflectionCardRoot>
       </RemoteReflectionModal>
diff --git a/packages/client/components/RetroReflectPhase/HTMLReflection.tsx b/packages/client/components/RetroReflectPhase/HTMLReflection.tsx
index 078e18d98a0..6e14b231f15 100644
--- a/packages/client/components/RetroReflectPhase/HTMLReflection.tsx
+++ b/packages/client/components/RetroReflectPhase/HTMLReflection.tsx
@@ -8,10 +8,10 @@ interface Props {
 export const HTMLReflection = (props: Props) => {
   const {html, disableAnonymity} = props
   return (
-    <div className={cn('relative w-full overflow-auto text-sm leading-4 text-slate-700')}>
+    <div className={cn('relative w-full overflow-auto text-sm leading-5 text-slate-700')}>
       <div
         className={cn(
-          'ProseMirror flex max-h-28 min-h-4 w-full flex-col items-start justify-center px-4 pt-3 leading-none',
+          'ProseMirror flex max-h-41 min-h-6 w-full flex-col items-start justify-center px-4 pt-3 leading-5',
           disableAnonymity ? 'pb-0' : 'pb-3'
         )}
         dangerouslySetInnerHTML={{__html: html}}
diff --git a/packages/client/components/RetroReflectPhase/PhaseItemEditor.tsx b/packages/client/components/RetroReflectPhase/PhaseItemEditor.tsx
index 56d67fe88f8..e6690fd40bc 100644
--- a/packages/client/components/RetroReflectPhase/PhaseItemEditor.tsx
+++ b/packages/client/components/RetroReflectPhase/PhaseItemEditor.tsx
@@ -250,7 +250,7 @@ const PhaseItemEditor = (props: Props) => {
       <ReflectionCardRoot data-cy={dataCy} ref={phaseEditorRef} className=''>
         <TipTapEditor
           className={cn(
-            'flex max-h-28 min-h-0 overflow-auto px-4 pt-3',
+            'flex max-h-41 min-h-6 overflow-auto px-4 pt-3',
             disableAnonymity ? 'pb-0' : 'pb-3'
           )}
           editor={editor}
@@ -258,7 +258,9 @@ const PhaseItemEditor = (props: Props) => {
           onFocus={onFocus}
         />
         {disableAnonymity && (
-          <ReflectionCardAuthor>{viewerMeetingMember?.user.preferredName}</ReflectionCardAuthor>
+          <div className='pb-3'>
+            <ReflectionCardAuthor>{viewerMeetingMember?.user.preferredName}</ReflectionCardAuthor>
+          </div>
         )}
         <EnterHint visible={!!enterHint} onClick={handleSubmit}>
           {enterHint}
@@ -275,11 +277,15 @@ const PhaseItemEditor = (props: Props) => {
                 isStart={card.isStart}
                 onTransitionEnd={removeCardInFlight(card.key)}
               >
-                <HTMLReflection html={card.html} disableAnonymity={disableAnonymity} />
+                <div className='py-[2px]'>
+                  <HTMLReflection html={card.html} disableAnonymity={disableAnonymity} />
+                </div>
                 {disableAnonymity && (
-                  <ReflectionCardAuthor>
-                    {viewerMeetingMember?.user.preferredName}
-                  </ReflectionCardAuthor>
+                  <div className='pb-3'>
+                    <ReflectionCardAuthor>
+                      {viewerMeetingMember?.user.preferredName}
+                    </ReflectionCardAuthor>
+                  </div>
                 )}
               </CardInFlightStyles>
             )
diff --git a/packages/client/components/TeamPrompt/TeamPromptGridDimensions.ts b/packages/client/components/TeamPrompt/TeamPromptGridDimensions.ts
index e7ebae59e17..938d7e68173 100644
--- a/packages/client/components/TeamPrompt/TeamPromptGridDimensions.ts
+++ b/packages/client/components/TeamPrompt/TeamPromptGridDimensions.ts
@@ -1,5 +1,5 @@
 export const ResponseCardDimensions = {
-  MIN_CARD_HEIGHT: 100,
+  MIN_CARD_HEIGHT: 92,
   GAP: 32,
   MIN_RESPONSE_WIDTH: 320
 }
diff --git a/packages/client/components/ThreadedAvatarColumn.tsx b/packages/client/components/ThreadedAvatarColumn.tsx
index 53473dc7d6d..6ec4114950a 100644
--- a/packages/client/components/ThreadedAvatarColumn.tsx
+++ b/packages/client/components/ThreadedAvatarColumn.tsx
@@ -4,7 +4,7 @@ import Avatar from './Avatar/Avatar'
 const AvatarCol = styled('div')<{isReply: boolean | undefined}>(({isReply}) => ({
   display: 'flex',
   paddingRight: 8,
-  paddingLeft: isReply ? undefined : 8
+  paddingLeft: isReply ? undefined : 12
 }))
 
 interface Props {
diff --git a/packages/client/components/ThreadedCommentBase.tsx b/packages/client/components/ThreadedCommentBase.tsx
index f1625e586e3..52096ab6c33 100644
--- a/packages/client/components/ThreadedCommentBase.tsx
+++ b/packages/client/components/ThreadedCommentBase.tsx
@@ -169,7 +169,7 @@ const ThreadedCommentBase = (props: Props) => {
   return (
     <ThreadedItemWrapper isReply={isReply}>
       <ThreadedAvatarColumn isReply={isReply} picture={picture} />
-      <div className='flex w-[calc(100%-56px)] flex-col pb-2'>
+      <div className='flex w-[calc(100%-56px)] flex-col pb-3'>
         <ThreadedCommentHeader
           comment={comment}
           editComment={editComment}
diff --git a/packages/client/components/ThreadedItemHeaderDescription.tsx b/packages/client/components/ThreadedItemHeaderDescription.tsx
index e48bdf5271e..f94a6482cdb 100644
--- a/packages/client/components/ThreadedItemHeaderDescription.tsx
+++ b/packages/client/components/ThreadedItemHeaderDescription.tsx
@@ -7,7 +7,7 @@ const Header = styled('div')({
   fontSize: 12,
   lineHeight: '12px',
   justifyContent: 'space-between',
-  paddingBottom: 8,
+  padding: '4px 0 0',
   width: '100%'
 })
 
diff --git a/packages/client/components/ThreadedTaskBase.tsx b/packages/client/components/ThreadedTaskBase.tsx
index 6185efee089..8855fad25b8 100644
--- a/packages/client/components/ThreadedTaskBase.tsx
+++ b/packages/client/components/ThreadedTaskBase.tsx
@@ -108,7 +108,9 @@ const ThreadedTaskBase = (props: Props) => {
             <ThreadedReplyButton onReply={onReply} />
           </HeaderActions>
         </ThreadedItemHeaderDescription>
-        <StyledNullableTask area='meeting' task={task} />
+        <div className='py-2'>
+          <StyledNullableTask area='meeting' task={task} />
+        </div>
         {repliesList}
         {replyingTo?.id === task.id && (
           <DiscussionThreadInput
diff --git a/packages/client/components/promptResponse/TipTapEditor.tsx b/packages/client/components/promptResponse/TipTapEditor.tsx
index 7736e0cfcdc..d5a8f655408 100644
--- a/packages/client/components/promptResponse/TipTapEditor.tsx
+++ b/packages/client/components/promptResponse/TipTapEditor.tsx
@@ -18,7 +18,7 @@ export const TipTapEditor = (props: Props) => {
         ref={ref as any}
         {...rest}
         editor={editor}
-        className={cn('min-h-10 px-4 text-sm leading-none', className)}
+        className={cn('min-h-6 text-sm', className)}
       />
     </>
   )
diff --git a/packages/client/modules/outcomeCard/components/OutcomeCard/OutcomeCard.tsx b/packages/client/modules/outcomeCard/components/OutcomeCard/OutcomeCard.tsx
index 2b56844e8da..a548758fe22 100644
--- a/packages/client/modules/outcomeCard/components/OutcomeCard/OutcomeCard.tsx
+++ b/packages/client/modules/outcomeCard/components/OutcomeCard/OutcomeCard.tsx
@@ -181,6 +181,7 @@ const OutcomeCard = memo((props: Props) => {
             onFocus={() => addTaskChild('root')}
           >
             <TipTapEditor
+              className='px-4'
               editor={editor}
               useLinkEditor={() => useTaskChild('editor-link-changer')}
               onBlur={onFocusChange(false)}
diff --git a/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooter.tsx b/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooter.tsx
index 2402156e078..bc1c2d58c07 100644
--- a/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooter.tsx
+++ b/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooter.tsx
@@ -24,7 +24,7 @@ const Footer = styled('div')({
   display: 'flex',
   justifyContent: 'space-between',
   maxWidth: '100%',
-  padding: `12px ${Card.PADDING} ${Card.PADDING}`
+  padding: `8px ${Card.PADDING} ${Card.PADDING}`
 })
 
 const ButtonGroup = styled('div')<{cardIsActive: boolean}>(({cardIsActive}) => ({
@@ -119,7 +119,6 @@ const TaskFooter = (props: Props) => {
             <TaskFooterUserAssignee
               area={area}
               canAssign={canAssignUser}
-              cardIsActive={cardIsActive}
               task={task}
               useTaskChild={useTaskChild}
             />
diff --git a/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooterTeamAssignee.tsx b/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooterTeamAssignee.tsx
index 501517a874f..86df4398217 100644
--- a/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooterTeamAssignee.tsx
+++ b/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooterTeamAssignee.tsx
@@ -27,7 +27,7 @@ const TeamToggleButton = styled(CardButton)({
   color: PALETTE.SLATE_600,
   display: 'block',
   fontSize: 12,
-  fontWeight: 400,
+  fontWeight: 600,
   height: 24,
   lineHeight: '24px',
   marginLeft: -8,
diff --git a/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooterUserAssignee.tsx b/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooterUserAssignee.tsx
index 43e766a8e17..e35b9123bc7 100644
--- a/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooterUserAssignee.tsx
+++ b/packages/client/modules/outcomeCard/components/OutcomeCardFooter/TaskFooterUserAssignee.tsx
@@ -44,22 +44,14 @@ const AvatarButton = styled(BaseButton)({
   }
 })
 
-const Avatar = styled('div')<{cardIsActive: boolean; isAssigned: boolean}>(
-  ({cardIsActive, isAssigned}) => ({
-    backgroundColor: isAssigned ? 'transparent' : PALETTE.SLATE_600,
-    color: isAssigned ? 'transparent' : undefined,
-    border: '1px solid transparent',
-    borderColor: cardIsActive ? PALETTE.SLATE_500 : undefined,
-    borderRadius: '100%',
-    height: 28,
-    marginLeft: -2,
-    marginRight: 4,
-    padding: 1,
-    position: 'relative',
-    top: -2,
-    width: 28
-  })
-)
+const Avatar = styled('div')<{isAssigned: boolean}>(({isAssigned}) => ({
+  backgroundColor: isAssigned ? 'transparent' : PALETTE.SLATE_600,
+  color: isAssigned ? 'transparent' : undefined,
+  borderRadius: '100%',
+  height: 24,
+  marginRight: 6,
+  width: 24
+}))
 
 const AvatarImage = styled('img')({
   borderRadius: '100%',
@@ -72,6 +64,7 @@ const AvatarLabel = styled('div')({
   ...label,
   color: PALETTE.SLATE_600,
   flex: 1,
+  fontWeight: 600,
   minWidth: 0,
   overflowWrap: 'break-word'
 })
@@ -100,7 +93,6 @@ const StyledIcon = styled('div')({
 interface Props {
   area: string
   canAssign: boolean
-  cardIsActive: boolean
   task: TaskFooterUserAssignee_task$key
   useTaskChild: UseTaskChild
 }
@@ -113,7 +105,7 @@ const TaskFooterUserAssigneeMenuRoot = lazyPreload(
 )
 
 const TaskFooterUserAssignee = (props: Props) => {
-  const {area, canAssign, cardIsActive, task: taskRef, useTaskChild} = props
+  const {area, canAssign, task: taskRef, useTaskChild} = props
   const task = useFragment(
     graphql`
       fragment TaskFooterUserAssignee_task on Task {
@@ -153,7 +145,7 @@ const TaskFooterUserAssignee = (props: Props) => {
           onMouseEnter={TaskFooterUserAssigneeMenuRoot.preload}
           ref={originRef}
         >
-          <Avatar cardIsActive={cardIsActive} isAssigned={!!user}>
+          <Avatar isAssigned={!!user}>
             {user ? (
               <AvatarImage alt={preferredName} src={userImage} />
             ) : (
diff --git a/packages/client/modules/pages/Page.tsx b/packages/client/modules/pages/Page.tsx
index dfc309bde33..bae883803b8 100644
--- a/packages/client/modules/pages/Page.tsx
+++ b/packages/client/modules/pages/Page.tsx
@@ -20,7 +20,7 @@ export const Page = (props: Props) => {
   return (
     <div className='tems-center flex w-full justify-center bg-slate-200 pt-2'>
       <div className='flex min-h-screen w-full max-w-[960px] justify-center bg-white pt-28'>
-        <TipTapEditor editor={editor} className='flex w-full' />
+        <TipTapEditor editor={editor} className='flex w-full px-6' />
       </div>
     </div>
   )
diff --git a/packages/client/styles/theme/global.css b/packages/client/styles/theme/global.css
index 747d8df09a8..55bacff77c1 100644
--- a/packages/client/styles/theme/global.css
+++ b/packages/client/styles/theme/global.css
@@ -380,6 +380,8 @@
 
 .ProseMirror {
   width: 100%;
+  /* Match top padding for more consistent vertical alignment */
+  padding-bottom: 2px;
   /* Gap cursor is 2px above the top of an element */
   padding-top: 2px;
   blockquote {
@@ -502,7 +504,16 @@
 .ProseMirror p {
   margin-block-start: 4px;
   margin-block-end: 4px;
-  line-height: 1rem;
+  /* Line height: for now most editable surfaces are 14/20 */
+  line-height: 1.4285714286;
+}
+
+.ProseMirror p:first-of-type {
+  margin-block-start: 0;
+}
+
+.ProseMirror p:last-of-type {
+  margin-block-end: 0;
 }
 
 hr.ProseMirror-selectednode {


Reviews:
user: login: mattkrick
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-28T20:44:47Z
user: login: ackernaut
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T18:13:39Z
user: login: ackernaut
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T18:15:17Z

Review comments:
diff_hunk: @@ -317,18 +317,18 @@ const ReflectionCard = (props: Props) => {
       onMouseLeave={() => setIsHovering(false)}
       showDragHintAnimation={showDragHintAnimation}
       ref={reflectionDivRef}
-      className='py-2'
+      className='py-3'
     >
       <ColorBadge phaseType={phaseType as NewMeetingPhaseTypeEnum} reflection={reflection} />
 
       <div
         ref={scrollRef}
-        className={cn('relative w-full overflow-auto text-sm leading-4 text-slate-700')}
+        className={cn('relative w-full overflow-auto text-sm leading-5 text-slate-700')}
       >
         <TipTapEditor
           className={cn(
-            'flex min-h-4 w-full px-4',
-            isClipped ? 'max-h-8' : 'max-h-28',
+            'flex min-h-6 w-full px-4',
+            phaseType === 'discuss' ? 'min-h-0' : isClipped ? 'max-h-6' : 'max-h-41',
path: packages/client/components/ReflectionCard/ReflectionCard.tsx
user: login: mattkrick
body: +1 this seems like an odd ternary-- either it has a min-h OR a max-h? would it be better to say `phaseType === 'discuss' && 'min-h-0' ` as a separate line item?
created_at: 2025-02-28T20:30:42Z
author_association: MEMBER
diff_hunk: @@ -495,7 +497,16 @@
 .ProseMirror p {
   margin-block-start: 4px;
   margin-block-end: 4px;
-  line-height: 1rem;
+  /* Line height: for now most editable surfaces are 14/20 */
+  line-height: 1.4285714286em;
path: packages/client/styles/theme/global.css
user: login: mattkrick
body: Is `em` intended? That might get tricky when we add font sizes to tiptap. I did a little digging & saw inheritance gets tricky with units, but unitless is a little cleaner https://developer.mozilla.org/en-US/docs/Web/CSS/line-height#prefer_unitless_numbers_for_line-height_values 
created_at: 2025-02-28T20:43:40Z
author_association: MEMBER
diff_hunk: @@ -495,7 +497,16 @@
 .ProseMirror p {
   margin-block-start: 4px;
   margin-block-end: 4px;
-  line-height: 1rem;
+  /* Line height: for now most editable surfaces are 14/20 */
+  line-height: 1.4285714286em;
path: packages/client/styles/theme/global.css
user: login: ackernaut
body: Ah, good point! I can yank the `em` unit. In the future, I want to find a good way to set up the base font size as 16px for pages, and 14px for cards, comments, etc. but we shall see.
created_at: 2025-03-03T18:13:39Z
author_association: MEMBER
diff_hunk: @@ -317,18 +317,18 @@ const ReflectionCard = (props: Props) => {
       onMouseLeave={() => setIsHovering(false)}
       showDragHintAnimation={showDragHintAnimation}
       ref={reflectionDivRef}
-      className='py-2'
+      className='py-3'
     >
       <ColorBadge phaseType={phaseType as NewMeetingPhaseTypeEnum} reflection={reflection} />
 
       <div
         ref={scrollRef}
-        className={cn('relative w-full overflow-auto text-sm leading-4 text-slate-700')}
+        className={cn('relative w-full overflow-auto text-sm leading-5 text-slate-700')}
       >
         <TipTapEditor
           className={cn(
-            'flex min-h-4 w-full px-4',
-            isClipped ? 'max-h-8' : 'max-h-28',
+            'flex min-h-6 w-full px-4',
+            phaseType === 'discuss' ? 'min-h-0' : isClipped ? 'max-h-6' : 'max-h-41',
path: packages/client/components/ReflectionCard/ReflectionCard.tsx
user: login: ackernaut
body: Actually, what I should do is not set anything if it’s the discuss phase, otherwise set a max-height based on if `isClipped` or not. I want to allow the full size of the cards during discuss. The only change I want to make here is to set it `undefined` not `min-h-0` which is inaccurate, unnecessary. Good eye!
created_at: 2025-03-03T18:15:17Z
author_association: MEMBER

PR comments:
user: login: ackernaut
created_at: 2025-03-03T18:17:57Z
body: Ready to merge, I addressed the changes @mattkrick . Shall I push it through?
author_association: MEMBER
user: login: mattkrick
created_at: 2025-03-05T16:58:22Z
body: LGTM!
author_association: MEMBER